29#ifndef ETL_CALLBACK_TIMER_INCLUDED
30#define ETL_CALLBACK_TIMER_INCLUDED
36#include "static_assert.h"
45#if defined(ETL_IN_UNIT_TEST) && ETL_NOT_USING_STL
46 #define ETL_DISABLE_TIMER_UPDATES
47 #define ETL_ENABLE_TIMER_UPDATES
48 #define ETL_TIMER_UPDATES_ENABLED true
50 #undef ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK
51 #undef ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK
53 #if !defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK) && !defined(ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK)
54 #error ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK or ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK not defined
57 #if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK) && defined(ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK)
58 #error Only define one of ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK or ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK
61 #if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
62 #define ETL_DISABLE_TIMER_UPDATES (++process_semaphore)
63 #define ETL_ENABLE_TIMER_UPDATES (--process_semaphore)
64 #define ETL_TIMER_UPDATES_ENABLED (process_semaphore.load() == 0)
68#if defined(ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK)
69 #if !defined(ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS) || !defined(ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS)
70 #error ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS and/or ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS not defined
73 #define ETL_DISABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS
74 #define ETL_ENABLE_TIMER_UPDATES ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS
75 #define ETL_TIMER_UPDATES_ENABLED true
98 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
100 bool is_space = (registered_timers < MAX_TIMERS);
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);
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);
172 timer_data&
timer = timer_array[i];
174 if (
timer.
id == etl::timer::id::NO_TIMER)
196 if (
id_ != etl::timer::id::NO_TIMER)
200 if (
timer.
id != etl::timer::id::NO_TIMER)
202 if (
timer.is_active())
205 active_list.remove(
timer.
id,
false);
206 remove_callback.call_if(
timer.
id);
246 for (
int i = 0; i < MAX_TIMERS; ++i)
251 registered_timers = 0;
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)
300 else if(timer.cbk_type == timer_data::DELEGATE)
303 (*
reinterpret_cast<callback_type*
>(timer.p_callback))();
313 active_list.front().delta -= count;
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)
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);
370 if (
id_ != etl::timer::id::NO_TIMER)
375 if (
timer.
id != etl::timer::id::NO_TIMER)
377 if (
timer.is_active())
380 active_list.remove(
timer.
id,
false);
381 remove_callback.call_if(
timer.
id);
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();
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)
533 , delta(
etl::
timer::state::Inactive)
535 , previous(
etl::
timer::id::NO_TIMER)
538 , cbk_type(C_CALLBACK)
551 , delta(
etl::
timer::state::Inactive)
553 , previous(
etl::
timer::id::NO_TIMER)
556 , cbk_type(IFUNCTION)
583 return delta != etl::timer::state::Inactive;
591 delta = etl::timer::state::Inactive;
597 etl::timer::id::type id;
601 callback_type_id cbk_type;
618 process_semaphore(0),
620 registered_timers(0),
630 bool is_valid_timer_id(etl::timer::id::type
id_)
const
632 return (
id_ < MAX_TIMERS);
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;
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;
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;
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;
818 timer_data*
const timer_array;
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)
832 #error No atomic type available
840 event_callback_type insert_callback;
841 event_callback_type remove_callback;
851 template <const u
int_least8_t Max_Timers_>
856 ETL_STATIC_ASSERT(
Max_Timers_ <= 254,
"No more than 254 timers are allowed");
872#undef ETL_DISABLE_TIMER_UPDATES
873#undef ETL_ENABLE_TIMER_UPDATES
874#undef ETL_TIMER_UPDATES_ENABLED
The callback timer.
Definition callback_timer.h:853
callback_timer()
Constructor.
Definition callback_timer.h:861
Declaration.
Definition delegate_cpp03.h:191
Interface for callback timer.
Definition callback_timer.h:84
bool unregister_timer(etl::timer::id::type id_)
Register a timer.
Definition callback_timer.h:192
bool is_running() const
Get the enable/disable state.
Definition callback_timer.h:232
bool set_period(etl::timer::id::type id_, uint32_t period_)
Sets a timer's period.
Definition callback_timer.h:395
etl::timer::id::type register_timer(void(*p_callback_)(), uint32_t period_, bool repeating_)
Register a timer.
Definition callback_timer.h:94
void set_insert_callback(event_callback_type insert_)
Set a callback when a timer is inserted on list.
Definition callback_timer.h:471
bool start(etl::timer::id::type id_, bool immediate_=false)
Starts a timer.
Definition callback_timer.h:327
bool set_mode(etl::timer::id::type id_, bool repeating_)
Sets a timer's mode.
Definition callback_timer.h:409
uint32_t time_to_next() const
Definition callback_timer.h:432
bool has_active_timer() const
Check if there is an active timer.
Definition callback_timer.h:423
void set_remove_callback(event_callback_type remove_)
Set a callback when a timer is removed from list.
Definition callback_timer.h:479
bool stop(etl::timer::id::type id_)
Stops a timer.
Definition callback_timer.h:365
void enable(bool state_)
Enable/disable the timer.
Definition callback_timer.h:224
etl::timer::id::type register_timer(etl::ifunction< void > &callback_, uint32_t period_, bool repeating_)
Register a timer.
Definition callback_timer.h:126
bool is_active(etl::timer::id::type id_) const
Definition callback_timer.h:448
icallback_timer(timer_data *const timer_array_, const uint_least8_t Max_Timers_)
Constructor.
Definition callback_timer.h:613
void clear()
Clears the timer of data.
Definition callback_timer.h:240
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2300
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:315
The configuration of a timer.
Definition callback_timer.h:501
timer_data(etl::timer::id::type id_, callback_type &callback_, uint32_t period_, bool repeating_)
ETL delegate callback.
Definition callback_timer.h:563
bool is_active() const
Returns true if the timer is active.
Definition callback_timer.h:581
void set_inactive()
Sets the timer to the inactive state.
Definition callback_timer.h:589
timer_data(etl::timer::id::type id_, etl::ifunction< void > &callback_, uint32_t period_, bool repeating_)
ETL function callback.
Definition callback_timer.h:545
timer_data(etl::timer::id::type id_, void(*p_callback_)(), uint32_t period_, bool repeating_)
C function callback.
Definition callback_timer.h:527
Common definitions for the timer framework.
Definition timer.h:55