89 typedef etl::delegate<void(etl::timer::id::type)> event_callback_type;
98 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
100 bool is_space = (registered_timers < MAX_TIMERS);
105 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
109 if (
timer.
id == etl::timer::id::NO_TIMER)
130 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
132 bool is_space = (registered_timers < MAX_TIMERS);
137 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
141 if (
timer.
id == etl::timer::id::NO_TIMER)
163 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
165 bool is_space = (registered_timers < MAX_TIMERS);
170 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
172 timer_data&
timer = timer_array[i];
174 if (
timer.
id == etl::timer::id::NO_TIMER)
177 new (&
timer) timer_data(i, callback_, period_, repeating_);
196 if (id_ != etl::timer::id::NO_TIMER)
200 if (
timer.
id != etl::timer::id::NO_TIMER)
202 if (
timer.is_active())
204 ETL_DISABLE_TIMER_UPDATES;
205 active_list.remove(
timer.
id,
false);
206 remove_callback.call_if(
timer.
id);
207 ETL_ENABLE_TIMER_UPDATES;
242 ETL_DISABLE_TIMER_UPDATES;
244 ETL_ENABLE_TIMER_UPDATES;
246 for (
int i = 0; i < MAX_TIMERS; ++i)
251 registered_timers = 0;
260 bool tick(uint32_t count)
264 if (ETL_TIMER_UPDATES_ENABLED)
267 bool has_active = !active_list.empty();
271 while (has_active && (count >= active_list.front().delta))
273 timer_data&
timer = active_list.front();
275 count -=
timer.delta;
277 active_list.remove(
timer.
id,
true);
278 remove_callback.call_if(
timer.
id);
285 insert_callback.call_if(
timer.
id);
288 if (timer.p_callback != ETL_NULLPTR)
290 if (timer.cbk_type == timer_data::C_CALLBACK)
293 reinterpret_cast<void(*)()
>(timer.p_callback)();
295 else if(timer.cbk_type == timer_data::IFUNCTION)
298 (*
reinterpret_cast<etl::ifunction<void>*
>(timer.p_callback))();
300 else if(timer.cbk_type == timer_data::DELEGATE)
303 (*
reinterpret_cast<callback_type*
>(timer.p_callback))();
307 has_active = !active_list.empty();
313 active_list.front().delta -= count;
327 bool start(etl::timer::id::type id_,
bool immediate_ =
false)
332 if (id_ != etl::timer::id::NO_TIMER)
337 if (
timer.
id != etl::timer::id::NO_TIMER)
340 if (
timer.period != etl::timer::state::Inactive)
342 ETL_DISABLE_TIMER_UPDATES;
343 if (
timer.is_active())
345 active_list.remove(
timer.
id,
false);
346 remove_callback.call_if(
timer.
id);
351 insert_callback.call_if(
timer.
id);
352 ETL_ENABLE_TIMER_UPDATES;
365 bool stop(etl::timer::id::type id_)
370 if (id_ != etl::timer::id::NO_TIMER)
375 if (
timer.
id != etl::timer::id::NO_TIMER)
377 if (
timer.is_active())
379 ETL_DISABLE_TIMER_UPDATES;
380 active_list.remove(
timer.
id,
false);
381 remove_callback.call_if(
timer.
id);
382 ETL_ENABLE_TIMER_UPDATES;
399 timer_array[id_].period = period_;
409 bool set_mode(etl::timer::id::type id_,
bool repeating_)
413 timer_array[id_].repeating = repeating_;
425 return !active_list.empty();
434 uint32_t delta =
static_cast<uint32_t
>(etl::timer::interval::No_Active_Interval);
438 delta = active_list.front().delta;
451 if (is_valid_timer_id(id_))
458 if (
timer.
id != etl::timer::id::NO_TIMER)
460 return timer.is_active();
473 insert_callback = insert_;
481 remove_callback = remove_;
485 void clear_insert_callback()
487 insert_callback.clear();
491 void clear_remove_callback()
493 remove_callback.clear();
504 enum callback_type_id
513 : p_callback(ETL_NULLPTR)
515 , delta(etl::timer::state::Inactive)
516 , id(etl::timer::id::NO_TIMER)
517 , previous(etl::timer::id::NO_TIMER)
518 , next(etl::timer::id::NO_TIMER)
520 , cbk_type(IFUNCTION)
528 void (*p_callback_)(),
531 : p_callback(reinterpret_cast<void*>(p_callback_))
533 , delta(
etl::
timer::state::Inactive)
535 , previous(
etl::
timer::id::NO_TIMER)
537 , repeating(repeating_)
538 , cbk_type(C_CALLBACK)
549 : p_callback(reinterpret_cast<void*>(&callback_))
551 , delta(
etl::
timer::state::Inactive)
553 , previous(
etl::
timer::id::NO_TIMER)
555 , repeating(repeating_)
556 , cbk_type(IFUNCTION)
564 callback_type& callback_,
567 : p_callback(reinterpret_cast<void*>(&callback_)),
573 repeating(repeating_),
583 return delta != etl::timer::state::Inactive;
591 delta = etl::timer::state::Inactive;
597 etl::timer::id::type id;
598 uint_least8_t previous;
601 callback_type_id cbk_type;
614 : timer_array(timer_array_),
615 active_list(timer_array_),
617#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
618 process_semaphore(0),
620 registered_timers(0),
621 MAX_TIMERS(Max_Timers_)
630 bool is_valid_timer_id(etl::timer::id::type id_)
const
632 return (id_ < MAX_TIMERS);
641 timer_list(timer_data* ptimers_)
642 : head(
etl::timer::id::NO_TIMER)
643 , tail(
etl::timer::id::NO_TIMER)
644 , current(
etl::timer::id::NO_TIMER)
652 return head == etl::timer::id::NO_TIMER;
658 void insert(etl::timer::id::type id_)
660 timer_data& timer = ptimers[id_];
662 if (head == etl::timer::id::NO_TIMER)
667 timer.previous = etl::timer::id::NO_TIMER;
668 timer.next = etl::timer::id::NO_TIMER;
673 etl::timer::id::type test_id = begin();
675 while (test_id != etl::timer::id::NO_TIMER)
677 timer_data& test = ptimers[test_id];
680 if (timer.delta <= test.delta)
688 timer.previous = test.previous;
689 test.previous = timer.id;
690 timer.next = test.id;
693 test.delta -= timer.delta;
695 if (timer.previous != etl::timer::id::NO_TIMER)
697 ptimers[timer.previous].next = timer.id;
703 timer.delta -= test.delta;
706 test_id = next(test_id);
710 if (test_id == etl::timer::id::NO_TIMER)
713 ptimers[tail].next = timer.id;
714 timer.previous = tail;
715 timer.next = etl::timer::id::NO_TIMER;
722 void remove(etl::timer::id::type id_,
bool has_expired)
724 timer_data& timer = ptimers[id_];
732 ptimers[timer.previous].next = timer.next;
737 tail = timer.previous;
741 ptimers[timer.next].previous = timer.previous;
747 if (timer.next != etl::timer::id::NO_TIMER)
749 ptimers[timer.next].delta += timer.delta;
753 timer.previous = etl::timer::id::NO_TIMER;
754 timer.next = etl::timer::id::NO_TIMER;
755 timer.delta = etl::timer::state::Inactive;
761 return ptimers[head];
765 const timer_data& front()
const
767 return ptimers[head];
771 etl::timer::id::type begin()
778 etl::timer::id::type previous(etl::timer::id::type last)
780 current = ptimers[last].previous;
785 etl::timer::id::type next(etl::timer::id::type last)
787 current = ptimers[last].next;
794 etl::timer::id::type
id = begin();
796 while (
id != etl::timer::id::NO_TIMER)
798 timer_data& timer = ptimers[id];
800 timer.next = etl::timer::id::NO_TIMER;
803 head = etl::timer::id::NO_TIMER;
804 tail = etl::timer::id::NO_TIMER;
805 current = etl::timer::id::NO_TIMER;
810 etl::timer::id::type head;
811 etl::timer::id::type tail;
812 etl::timer::id::type current;
814 timer_data*
const ptimers;
821 timer_list active_list;
823 volatile bool enabled;
824#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
826#if defined(ETL_TIMER_SEMAPHORE_TYPE)
827 typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
830 typedef etl::atomic_uint16_t timer_semaphore_t;
832 #error No atomic type available
836 mutable etl::timer_semaphore_t process_semaphore;
838 uint_least8_t registered_timers;
840 event_callback_type insert_callback;
841 event_callback_type remove_callback;
845 const uint_least8_t MAX_TIMERS;