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
95 : p_callback(ETL_NULLPTR),
97 delta(etl::timer::state::Inactive),
98 id(etl::timer::id::NO_TIMER),
99 previous(etl::timer::id::NO_TIMER),
100 next(etl::timer::id::NO_TIMER),
165 return delta != etl::timer::state::Inactive;
173 delta = etl::timer::state::Inactive;
183 callback_type_id cbk_type;
192 namespace private_callback_timer
203 : head(etl::timer::id::NO_TIMER),
204 tail(etl::timer::id::NO_TIMER),
205 current(etl::timer::id::NO_TIMER),
213 return head == etl::timer::id::NO_TIMER;
223 if (head == etl::timer::id::NO_TIMER)
228 timer.previous = etl::timer::id::NO_TIMER;
229 timer.next = etl::timer::id::NO_TIMER;
236 while (
test_id != etl::timer::id::NO_TIMER)
241 if (
timer.delta <= test.delta)
249 timer.previous = test.previous;
251 timer.next = test.id;
254 test.delta -=
timer.delta;
256 if (
timer.previous != etl::timer::id::NO_TIMER)
264 timer.delta -= test.delta;
271 if (
test_id == etl::timer::id::NO_TIMER)
275 timer.previous = tail;
276 timer.next = etl::timer::id::NO_TIMER;
298 tail =
timer.previous;
302 ptimers[
timer.next].previous =
timer.previous;
308 if (
timer.next != etl::timer::id::NO_TIMER)
314 timer.previous = etl::timer::id::NO_TIMER;
315 timer.next = etl::timer::id::NO_TIMER;
316 timer.delta = etl::timer::state::Inactive;
322 return ptimers[head];
328 return ptimers[head];
341 current = ptimers[last].previous;
348 current = ptimers[last].next;
357 while (
id != etl::timer::id::NO_TIMER)
361 timer.next = etl::timer::id::NO_TIMER;
364 head = etl::timer::id::NO_TIMER;
365 tail = etl::timer::id::NO_TIMER;
366 current = etl::timer::id::NO_TIMER;
397 bool is_space = (registered_timers < MAX_TIMERS);
406 if (
timer.
id == etl::timer::id::NO_TIMER)
429 bool is_space = (registered_timers < MAX_TIMERS);
438 if (
timer.
id == etl::timer::id::NO_TIMER)
462 bool is_space = (registered_timers < MAX_TIMERS);
471 if (
timer.
id == etl::timer::id::NO_TIMER)
493 if (
id_ != etl::timer::id::NO_TIMER)
497 if (
timer.
id != etl::timer::id::NO_TIMER)
499 if (
timer.is_active())
502 active_list.remove(
timer.
id,
false);
542 for (
int i = 0;
i < MAX_TIMERS; ++
i)
547 registered_timers = 0;
567 while (
has_active && (count >= active_list.front().delta))
571 count -=
timer.delta;
573 active_list.remove(
timer.
id,
true);
582 if (timer.p_callback != ETL_NULLPTR)
584 if (timer.cbk_type == callback_timer_data::C_CALLBACK)
587 reinterpret_cast<void(*)()
>(timer.p_callback)();
589 else if(timer.cbk_type == callback_timer_data::IFUNCTION)
594 else if(timer.cbk_type == callback_timer_data::DELEGATE)
597 (*
reinterpret_cast<callback_type*
>(timer.p_callback))();
601 has_active = !active_list.empty();
607 active_list.front().delta -= count;
626 if (
id_ != etl::timer::id::NO_TIMER)
631 if (
timer.
id != etl::timer::id::NO_TIMER)
634 if (
timer.period != etl::timer::state::Inactive)
637 if (
timer.is_active())
639 active_list.remove(
timer.
id,
false);
662 if (
id_ != etl::timer::id::NO_TIMER)
667 if (
timer.
id != etl::timer::id::NO_TIMER)
669 if (
timer.is_active())
672 active_list.remove(
timer.
id,
false);
716 return !active_list.empty();
725 uint32_t delta =
static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
729 delta = active_list.front().delta;
742 if (is_valid_timer_id(
id_))
749 if (
timer.
id != etl::timer::id::NO_TIMER)
751 return timer.is_active();
769 process_semaphore(0),
771 registered_timers(0),
783 return (
id_ < MAX_TIMERS);
787 callback_timer_data*
const timer_array;
790 private_callback_timer::list active_list;
792 volatile bool enabled;
793#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
795#if defined(ETL_TIMER_SEMAPHORE_TYPE)
796 typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
801 #error No atomic type available
807 uint_least8_t registered_timers;
811 const uint_least8_t MAX_TIMERS;
817 template <const u
int_least8_t MAX_TIMERS_>
822 ETL_STATIC_ASSERT(
MAX_TIMERS_ <= 254,
"No more than 254 timers are allowed");
838#undef ETL_DISABLE_TIMER_UPDATES
839#undef ETL_ENABLE_TIMER_UPDATES
840#undef ETL_TIMER_UPDATES_ENABLED
The callback timer.
Definition callback_timer.h:819
callback_timer()
Constructor.
Definition callback_timer.h:827
Declaration.
Definition delegate_cpp03.h:175
Interface for callback timer.
Definition callback_timer.h:383
bool unregister_timer(etl::timer::id::type id_)
Register a timer.
Definition callback_timer.h:489
bool is_running() const
Get the enable/disable state.
Definition callback_timer.h:528
bool set_period(etl::timer::id::type id_, uint32_t period_)
Sets a timer's period.
Definition callback_timer.h:686
etl::timer::id::type register_timer(void(*p_callback_)(), uint32_t period_, bool repeating_)
Register a timer.
Definition callback_timer.h:391
bool start(etl::timer::id::type id_, bool immediate_=false)
Starts a timer.
Definition callback_timer.h:621
icallback_timer(callback_timer_data *const timer_array_, const uint_least8_t MAX_TIMERS_)
Constructor.
Definition callback_timer.h:764
bool set_mode(etl::timer::id::type id_, bool repeating_)
Sets a timer's mode.
Definition callback_timer.h:700
uint32_t time_to_next() const
Definition callback_timer.h:723
bool has_active_timer() const
Check if there is an active timer.
Definition callback_timer.h:714
bool stop(etl::timer::id::type id_)
Stops a timer.
Definition callback_timer.h:657
void enable(bool state_)
Enable/disable the timer.
Definition callback_timer.h:520
etl::timer::id::type register_timer(etl::ifunction< void > &callback_, uint32_t period_, bool repeating_)
Register a timer.
Definition callback_timer.h:423
bool is_active(etl::timer::id::type id_) const
Definition callback_timer.h:739
void clear()
Clears the timer of data.
Definition callback_timer.h:536
A specialised intrusive linked list for timer data.
Definition callback_timer.h:198
bitset_ext
Definition absolute.h:38
The configuration of a timer.
Definition callback_timer.h:83
callback_timer_data(etl::timer::id::type id_, void(*p_callback_)(), uint32_t period_, bool repeating_)
C function callback.
Definition callback_timer.h:109
callback_timer_data(etl::timer::id::type id_, etl::ifunction< void > &callback_, uint32_t period_, bool repeating_)
ETL function callback.
Definition callback_timer.h:127
bool is_active() const
Returns true if the timer is active.
Definition callback_timer.h:163
void set_inactive()
Sets the timer to the inactive state.
Definition callback_timer.h:171
callback_timer_data(etl::timer::id::type id_, callback_type &callback_, uint32_t period_, bool repeating_)
ETL delegate callback.
Definition callback_timer.h:145
pair holds two objects of arbitrary type
Definition utility.h:164
Common definitions for the timer framework.
Definition timer.h:55