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)
632 , current(
etl::timer::id::NO_TIMER)
640 return head == etl::timer::id::NO_TIMER;
646 void insert(etl::timer::id::type id_)
648 timer_data& timer = ptimers[id_];
650 if (head == etl::timer::id::NO_TIMER)
655 timer.previous = etl::timer::id::NO_TIMER;
656 timer.next = etl::timer::id::NO_TIMER;
661 etl::timer::id::type test_id = begin();
663 while (test_id != etl::timer::id::NO_TIMER)
665 timer_data& test = ptimers[test_id];
668 if (timer.delta <= test.delta)
676 timer.previous = test.previous;
677 test.previous = timer.id;
678 timer.next = test.id;
681 test.delta -= timer.delta;
683 if (timer.previous != etl::timer::id::NO_TIMER)
685 ptimers[timer.previous].next = timer.id;
691 timer.delta -= test.delta;
694 test_id = next(test_id);
698 if (test_id == etl::timer::id::NO_TIMER)
701 ptimers[tail].next = timer.id;
702 timer.previous = tail;
703 timer.next = etl::timer::id::NO_TIMER;
710 void remove(etl::timer::id::type id_,
bool has_expired)
712 timer_data& timer = ptimers[id_];
720 ptimers[timer.previous].next = timer.next;
725 tail = timer.previous;
729 ptimers[timer.next].previous = timer.previous;
735 if (timer.next != etl::timer::id::NO_TIMER)
737 ptimers[timer.next].delta += timer.delta;
741 timer.previous = etl::timer::id::NO_TIMER;
742 timer.next = etl::timer::id::NO_TIMER;
743 timer.delta = etl::timer::state::Inactive;
749 return ptimers[head];
753 const timer_data& front()
const
755 return ptimers[head];
759 etl::timer::id::type begin()
766 etl::timer::id::type previous(etl::timer::id::type last)
768 current = ptimers[last].previous;
773 etl::timer::id::type next(etl::timer::id::type last)
775 current = ptimers[last].next;
782 etl::timer::id::type
id = begin();
784 while (
id != etl::timer::id::NO_TIMER)
786 timer_data& timer = ptimers[id];
788 timer.next = etl::timer::id::NO_TIMER;
791 head = etl::timer::id::NO_TIMER;
792 tail = etl::timer::id::NO_TIMER;
793 current = etl::timer::id::NO_TIMER;
798 etl::timer::id::type head;
799 etl::timer::id::type tail;
800 etl::timer::id::type current;
802 timer_data*
const ptimers;
809 timer_list active_list;
811 volatile bool enabled;
812#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
814 #if defined(ETL_TIMER_SEMAPHORE_TYPE)
815 typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
818 typedef etl::atomic_uint16_t timer_semaphore_t;
820 #error No atomic type available
824 mutable etl::timer_semaphore_t process_semaphore;
826 uint_least8_t registered_timers;
828 event_callback_type insert_callback;
829 event_callback_type remove_callback;
833 const uint_least8_t MAX_TIMERS;