89 typedef etl::delegate<void(etl::timer::id::type)> event_callback_type;
94 etl::timer::id::type
register_timer(
void (*p_callback_)(), uint32_t period_,
bool repeating_)
96 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
98 bool is_space = (registered_timers < MAX_TIMERS);
103 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
107 if (
timer.
id == etl::timer::id::NO_TIMER)
126 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
128 bool is_space = (registered_timers < MAX_TIMERS);
133 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
137 if (
timer.
id == etl::timer::id::NO_TIMER)
157 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
159 bool is_space = (registered_timers < MAX_TIMERS);
164 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
166 timer_data&
timer = timer_array[i];
168 if (
timer.
id == etl::timer::id::NO_TIMER)
171 new (&
timer) timer_data(i, callback_, period_, repeating_);
190 if (id_ != etl::timer::id::NO_TIMER)
194 if (
timer.
id != etl::timer::id::NO_TIMER)
196 if (
timer.is_active())
198 ETL_DISABLE_TIMER_UPDATES;
199 active_list.remove(
timer.
id,
false);
200 remove_callback.call_if(
timer.
id);
201 ETL_ENABLE_TIMER_UPDATES;
236 ETL_DISABLE_TIMER_UPDATES;
238 ETL_ENABLE_TIMER_UPDATES;
240 for (
int i = 0; i < MAX_TIMERS; ++i)
245 registered_timers = 0;
254 bool tick(uint32_t count)
258 if (ETL_TIMER_UPDATES_ENABLED)
261 bool has_active = !active_list.empty();
265 while (has_active && (count >= active_list.front().delta))
267 timer_data&
timer = active_list.front();
269 count -=
timer.delta;
271 active_list.remove(
timer.
id,
true);
272 remove_callback.call_if(
timer.
id);
279 insert_callback.call_if(
timer.
id);
282 if (timer.p_callback != ETL_NULLPTR)
284 if (timer.cbk_type == timer_data::C_CALLBACK)
287 reinterpret_cast<void (*)()
>(timer.p_callback)();
289 else if (timer.cbk_type == timer_data::IFUNCTION)
292 (*
reinterpret_cast<etl::ifunction<void>*
>(timer.p_callback))();
294 else if (timer.cbk_type == timer_data::DELEGATE)
297 (*
reinterpret_cast<callback_type*
>(timer.p_callback))();
301 has_active = !active_list.empty();
307 active_list.front().delta -= count;
321 bool start(etl::timer::id::type id_,
bool immediate_ =
false)
326 if (id_ != etl::timer::id::NO_TIMER)
331 if (
timer.
id != etl::timer::id::NO_TIMER)
334 if (
timer.period != etl::timer::state::Inactive)
336 ETL_DISABLE_TIMER_UPDATES;
337 if (
timer.is_active())
339 active_list.remove(
timer.
id,
false);
340 remove_callback.call_if(
timer.
id);
345 insert_callback.call_if(
timer.
id);
346 ETL_ENABLE_TIMER_UPDATES;
359 bool stop(etl::timer::id::type id_)
364 if (id_ != etl::timer::id::NO_TIMER)
369 if (
timer.
id != etl::timer::id::NO_TIMER)
371 if (
timer.is_active())
373 ETL_DISABLE_TIMER_UPDATES;
374 active_list.remove(
timer.
id,
false);
375 remove_callback.call_if(
timer.
id);
376 ETL_ENABLE_TIMER_UPDATES;
393 timer_array[id_].period = period_;
403 bool set_mode(etl::timer::id::type id_,
bool repeating_)
407 timer_array[id_].repeating = repeating_;
419 return !active_list.empty();
429 uint32_t delta =
static_cast<uint32_t
>(etl::timer::interval::No_Active_Interval);
433 delta = active_list.front().delta;
446 if (is_valid_timer_id(id_))
453 if (
timer.
id != etl::timer::id::NO_TIMER)
455 return timer.is_active();
468 insert_callback = insert_;
476 remove_callback = remove_;
480 void clear_insert_callback()
482 insert_callback.clear();
486 void clear_remove_callback()
488 remove_callback.clear();
499 enum callback_type_id
508 : p_callback(ETL_NULLPTR)
510 , delta(etl::timer::state::Inactive)
511 , id(etl::timer::id::NO_TIMER)
512 , previous(etl::timer::id::NO_TIMER)
513 , next(etl::timer::id::NO_TIMER)
515 , cbk_type(IFUNCTION)
522 timer_data(etl::timer::id::type id_,
void (*p_callback_)(), uint32_t period_,
bool repeating_)
523 : p_callback(reinterpret_cast<void*>(p_callback_))
525 , delta(
etl::
timer::state::Inactive)
527 , previous(
etl::
timer::id::NO_TIMER)
529 , repeating(repeating_)
530 , cbk_type(C_CALLBACK)
538 : p_callback(reinterpret_cast<void*>(&callback_))
540 , delta(
etl::
timer::state::Inactive)
542 , previous(
etl::
timer::id::NO_TIMER)
544 , repeating(repeating_)
545 , cbk_type(IFUNCTION)
552 timer_data(etl::timer::id::type id_, callback_type& callback_, uint32_t period_,
bool repeating_)
553 : p_callback(reinterpret_cast<void*>(&callback_))
555 , delta(
etl::
timer::state::Inactive)
557 , previous(
etl::
timer::id::NO_TIMER)
559 , repeating(repeating_)
569 return delta != etl::timer::state::Inactive;
577 delta = etl::timer::state::Inactive;
583 etl::timer::id::type id;
584 uint_least8_t previous;
587 callback_type_id cbk_type;
600 : timer_array(timer_array_)
601 , active_list(timer_array_)
604#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
609 , MAX_TIMERS(Max_Timers_)
618 bool is_valid_timer_id(etl::timer::id::type id_)
const
620 return (id_ < MAX_TIMERS);
629 timer_list(timer_data* ptimers_)
630 : head(
etl::timer::id::NO_TIMER)
631 , tail(
etl::timer::id::NO_TIMER)
639 return head == etl::timer::id::NO_TIMER;
645 void insert(etl::timer::id::type id_)
647 timer_data& timer = ptimers[id_];
649 if (head == etl::timer::id::NO_TIMER)
654 timer.previous = etl::timer::id::NO_TIMER;
655 timer.next = etl::timer::id::NO_TIMER;
660 etl::timer::id::type test_id = begin();
662 while (test_id != etl::timer::id::NO_TIMER)
664 timer_data& test = ptimers[test_id];
667 if (timer.delta <= test.delta)
675 timer.previous = test.previous;
676 test.previous = timer.id;
677 timer.next = test.id;
680 test.delta -= timer.delta;
682 if (timer.previous != etl::timer::id::NO_TIMER)
684 ptimers[timer.previous].next = timer.id;
690 timer.delta -= test.delta;
693 test_id = next(test_id);
697 if (test_id == etl::timer::id::NO_TIMER)
700 ptimers[tail].next = timer.id;
701 timer.previous = tail;
702 timer.next = etl::timer::id::NO_TIMER;
709 void remove(etl::timer::id::type id_,
bool has_expired)
711 timer_data& timer = ptimers[id_];
719 ptimers[timer.previous].next = timer.next;
724 tail = timer.previous;
728 ptimers[timer.next].previous = timer.previous;
734 if (timer.next != etl::timer::id::NO_TIMER)
736 ptimers[timer.next].delta += timer.delta;
740 timer.previous = etl::timer::id::NO_TIMER;
741 timer.next = etl::timer::id::NO_TIMER;
742 timer.delta = etl::timer::state::Inactive;
748 return ptimers[head];
752 const timer_data& front()
const
754 return ptimers[head];
758 etl::timer::id::type begin()
764 etl::timer::id::type next(etl::timer::id::type last)
766 return ptimers[last].next;
772 etl::timer::id::type
id = begin();
774 while (
id != etl::timer::id::NO_TIMER)
776 timer_data& timer = ptimers[id];
778 timer.next = etl::timer::id::NO_TIMER;
781 head = etl::timer::id::NO_TIMER;
782 tail = etl::timer::id::NO_TIMER;
787 etl::timer::id::type head;
788 etl::timer::id::type tail;
790 timer_data*
const ptimers;
797 timer_list active_list;
799 volatile bool enabled;
800#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
802 #if defined(ETL_TIMER_SEMAPHORE_TYPE)
803 typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
806 typedef etl::atomic_uint16_t timer_semaphore_t;
808 #error No atomic type available
812 mutable etl::timer_semaphore_t process_semaphore;
814 uint_least8_t registered_timers;
816 event_callback_type insert_callback;
817 event_callback_type remove_callback;
821 const uint_least8_t MAX_TIMERS;