54 typedef etl::delegate<void(etl::timer::id::type)> event_callback_type;
59 etl::timer::id::type
register_timer(
const callback_type& callback_, uint32_t period_,
bool repeating_)
61 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
63 bool is_space = (number_of_registered_timers < Max_Timers);
68 for (uint_least8_t i = 0U; i < Max_Timers; ++i)
70 timer_data&
timer = timer_array[i];
72 if (
timer.
id == etl::timer::id::NO_TIMER)
74 TInterruptGuard guard;
78 new (&
timer) timer_data(i, callback_, period_, repeating_);
79 ++number_of_registered_timers;
96 if (id_ != etl::timer::id::NO_TIMER)
98 timer_data&
timer = timer_array[id_];
100 if (
timer.
id != etl::timer::id::NO_TIMER)
102 if (
timer.is_active())
104 TInterruptGuard guard;
107 active_list.remove(
timer.
id,
false);
108 remove_callback.call_if(
timer.
id);
112 new (&
timer) timer_data();
113 --number_of_registered_timers;
144 TInterruptGuard guard;
148 number_of_registered_timers = 0;
151 for (uint8_t i = 0U; i < Max_Timers; ++i)
153 ::new (&timer_array[i]) timer_data();
163 bool tick(uint32_t count)
168 bool has_active = !active_list.empty();
172 while (has_active && (count >= active_list.front().delta))
174 timer_data&
timer = active_list.front();
176 count -=
timer.delta;
178 active_list.remove(
timer.
id,
true);
179 remove_callback.call_if(
timer.
id);
181 if (
timer.callback.is_valid())
189 timer.delta = timer.period;
190 active_list.insert(timer.id);
191 insert_callback.call_if(timer.id);
194 has_active = !active_list.empty();
200 active_list.front().delta -= count;
213 bool start(etl::timer::id::type id_,
bool immediate_ =
false)
218 if (id_ != etl::timer::id::NO_TIMER)
220 timer_data&
timer = timer_array[id_];
223 if (
timer.
id != etl::timer::id::NO_TIMER)
226 if (
timer.period != etl::timer::state::Inactive)
228 TInterruptGuard guard;
231 if (
timer.is_active())
233 active_list.remove(
timer.
id,
false);
234 remove_callback.call_if(
timer.
id);
239 insert_callback.call_if(
timer.
id);
252 bool stop(etl::timer::id::type id_)
257 if (id_ != etl::timer::id::NO_TIMER)
259 timer_data&
timer = timer_array[id_];
262 if (
timer.
id != etl::timer::id::NO_TIMER)
264 if (
timer.is_active())
266 TInterruptGuard guard;
269 active_list.remove(
timer.
id,
false);
270 remove_callback.call_if(
timer.
id);
287 timer_array[id_].period = period_;
297 bool set_mode(etl::timer::id::type id_,
bool repeating_)
301 timer_array[id_].repeating = repeating_;
313 TInterruptGuard guard;
315 return !active_list.empty();
325 uint32_t delta =
static_cast<uint32_t
>(etl::timer::interval::No_Active_Interval);
327 TInterruptGuard guard;
330 if (!active_list.empty())
332 delta = active_list.front().delta;
345 if (is_valid_timer_id(id_))
349 TInterruptGuard guard;
352 const timer_data&
timer = timer_array[id_];
355 if (
timer.
id != etl::timer::id::NO_TIMER)
357 return timer.is_active();
370 insert_callback = insert_;
378 remove_callback = remove_;
382 void clear_insert_callback()
384 insert_callback.clear();
388 void clear_remove_callback()
390 remove_callback.clear();
403 , delta(etl::timer::state::Inactive)
404 , id(etl::timer::id::NO_TIMER)
405 , previous(etl::timer::id::NO_TIMER)
406 , next(etl::timer::id::NO_TIMER)
414 timer_data(etl::timer::id::type id_, callback_type callback_, uint32_t period_,
bool repeating_)
415 : callback(callback_)
417 , delta(
etl::
timer::state::Inactive)
419 , previous(
etl::
timer::id::NO_TIMER)
421 , repeating(repeating_)
430 return delta != etl::timer::state::Inactive;
438 delta = etl::timer::state::Inactive;
444 etl::timer::id::type id;
445 uint_least8_t previous;
460 : timer_array(timer_array_)
461 , active_list(timer_array_)
463 , number_of_registered_timers(0U)
464 , Max_Timers(Max_Timers_)
473 bool is_valid_timer_id(etl::timer::id::type id_)
const
475 return (id_ < Max_Timers);
486 timer_list(timer_data* ptimers_)
487 : head(
etl::timer::id::NO_TIMER)
488 , tail(
etl::timer::id::NO_TIMER)
496 return head == etl::timer::id::NO_TIMER;
502 void insert(etl::timer::id::type id_)
504 timer_data& timer = ptimers[id_];
506 if (head == etl::timer::id::NO_TIMER)
511 timer.previous = etl::timer::id::NO_TIMER;
512 timer.next = etl::timer::id::NO_TIMER;
517 etl::timer::id::type test_id = begin();
519 while (test_id != etl::timer::id::NO_TIMER)
521 timer_data& test = ptimers[test_id];
524 if (timer.delta <= test.delta)
532 timer.previous = test.previous;
533 test.previous = timer.id;
534 timer.next = test.id;
537 test.delta -= timer.delta;
539 if (timer.previous != etl::timer::id::NO_TIMER)
541 ptimers[timer.previous].next = timer.id;
547 timer.delta -= test.delta;
550 test_id = next(test_id);
554 if (test_id == etl::timer::id::NO_TIMER)
557 ptimers[tail].next = timer.id;
558 timer.previous = tail;
559 timer.next = etl::timer::id::NO_TIMER;
566 void remove(etl::timer::id::type id_,
bool has_expired)
568 timer_data& timer = ptimers[id_];
576 ptimers[timer.previous].next = timer.next;
581 tail = timer.previous;
585 ptimers[timer.next].previous = timer.previous;
591 if (timer.next != etl::timer::id::NO_TIMER)
593 ptimers[timer.next].delta += timer.delta;
597 timer.previous = etl::timer::id::NO_TIMER;
598 timer.next = etl::timer::id::NO_TIMER;
599 timer.delta = etl::timer::state::Inactive;
605 return ptimers[head];
609 const timer_data& front()
const
611 return ptimers[head];
615 etl::timer::id::type begin()
621 etl::timer::id::type next(etl::timer::id::type last)
623 return ptimers[last].next;
629 etl::timer::id::type
id = begin();
631 while (
id != etl::timer::id::NO_TIMER)
633 timer_data& timer = ptimers[id];
635 timer.next = etl::timer::id::NO_TIMER;
638 head = etl::timer::id::NO_TIMER;
639 tail = etl::timer::id::NO_TIMER;
644 etl::timer::id::type head;
645 etl::timer::id::type tail;
647 timer_data*
const ptimers;
654 timer_list active_list;
657 uint_least8_t number_of_registered_timers;
659 event_callback_type insert_callback;
660 event_callback_type remove_callback;
664 const uint_least8_t Max_Timers;