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),
110 void (*p_callback_)(),
113 : p_callback(reinterpret_cast<void*>(p_callback_)),
119 repeating(repeating_),
131 : p_callback(reinterpret_cast<void*>(&callback_)),
137 repeating(repeating_),
147 callback_type& callback_,
150 : p_callback(reinterpret_cast<void*>(&callback_)),
156 repeating(repeating_),
167 return delta != etl::timer::state::INACTIVE;
175 delta = etl::timer::state::INACTIVE;
181 etl::timer::id::type id;
182 uint_least8_t previous;
185 callback_type_id cbk_type;
194 namespace private_callback_timer
205 : head(etl::timer::id::NO_TIMER),
206 tail(etl::timer::id::NO_TIMER),
207 current(etl::timer::id::NO_TIMER),
215 return head == etl::timer::id::NO_TIMER;
221 void insert(etl::timer::id::type id_)
225 if (head == etl::timer::id::NO_TIMER)
230 timer.previous = etl::timer::id::NO_TIMER;
231 timer.next = etl::timer::id::NO_TIMER;
236 etl::timer::id::type test_id = begin();
238 while (test_id != etl::timer::id::NO_TIMER)
243 if (
timer.delta <= test.delta)
251 timer.previous = test.previous;
253 timer.next = test.id;
256 test.delta -=
timer.delta;
258 if (
timer.previous != etl::timer::id::NO_TIMER)
266 timer.delta -= test.delta;
269 test_id = next(test_id);
273 if (test_id == etl::timer::id::NO_TIMER)
277 timer.previous = tail;
278 timer.next = etl::timer::id::NO_TIMER;
285 void remove(etl::timer::id::type id_,
bool has_expired)
300 tail =
timer.previous;
304 ptimers[
timer.next].previous =
timer.previous;
310 if (
timer.next != etl::timer::id::NO_TIMER)
316 timer.previous = etl::timer::id::NO_TIMER;
317 timer.next = etl::timer::id::NO_TIMER;
318 timer.delta = etl::timer::state::INACTIVE;
324 return ptimers[head];
328 etl::timer::id::type begin()
335 etl::timer::id::type previous(etl::timer::id::type last)
337 current = ptimers[last].previous;
342 etl::timer::id::type next(etl::timer::id::type last)
344 current = ptimers[last].next;
351 etl::timer::id::type
id = begin();
353 while (
id != etl::timer::id::NO_TIMER)
357 timer.next = etl::timer::id::NO_TIMER;
360 head = etl::timer::id::NO_TIMER;
361 tail = etl::timer::id::NO_TIMER;
362 current = etl::timer::id::NO_TIMER;
367 etl::timer::id::type head;
368 etl::timer::id::type tail;
369 etl::timer::id::type current;
391 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
393 bool is_space = (registered_timers < MAX_TIMERS);
398 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
402 if (
timer.
id == etl::timer::id::NO_TIMER)
423 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
425 bool is_space = (registered_timers < MAX_TIMERS);
430 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
434 if (
timer.
id == etl::timer::id::NO_TIMER)
456 etl::timer::id::type
id = etl::timer::id::NO_TIMER;
458 bool is_space = (registered_timers < MAX_TIMERS);
463 for (uint_least8_t i = 0U; i < MAX_TIMERS; ++i)
467 if (
timer.
id == etl::timer::id::NO_TIMER)
489 if (id_ != etl::timer::id::NO_TIMER)
493 if (
timer.
id != etl::timer::id::NO_TIMER)
495 if (
timer.is_active())
497 ETL_DISABLE_TIMER_UPDATES;
498 active_list.remove(
timer.
id,
false);
499 ETL_ENABLE_TIMER_UPDATES;
534 ETL_DISABLE_TIMER_UPDATES;
536 ETL_ENABLE_TIMER_UPDATES;
538 for (
int i = 0; i < MAX_TIMERS; ++i)
543 registered_timers = 0;
552 bool tick(uint32_t count)
556 if (ETL_TIMER_UPDATES_ENABLED)
559 bool has_active = !active_list.empty();
563 while (has_active && (count >= active_list.front().delta))
567 count -=
timer.delta;
569 active_list.remove(
timer.
id,
true);
578 if (timer.p_callback != ETL_NULLPTR)
580 if (timer.cbk_type == callback_timer_data::C_CALLBACK)
583 reinterpret_cast<void(*)()
>(timer.p_callback)();
585 else if(timer.cbk_type == callback_timer_data::IFUNCTION)
591 else if(timer.cbk_type == callback_timer_data::DELEGATE)
594 (*
reinterpret_cast<callback_type*
>(timer.p_callback))();
599 has_active = !active_list.empty();
605 active_list.front().delta -= count;
619 bool start(etl::timer::id::type id_,
bool immediate_ =
false)
624 if (id_ != etl::timer::id::NO_TIMER)
629 if (
timer.
id != etl::timer::id::NO_TIMER)
632 if (
timer.period != etl::timer::state::INACTIVE)
634 ETL_DISABLE_TIMER_UPDATES;
635 if (
timer.is_active())
637 active_list.remove(
timer.
id,
false);
642 ETL_ENABLE_TIMER_UPDATES;
655 bool stop(etl::timer::id::type id_)
660 if (id_ != etl::timer::id::NO_TIMER)
665 if (
timer.
id != etl::timer::id::NO_TIMER)
667 if (
timer.is_active())
669 ETL_DISABLE_TIMER_UPDATES;
670 active_list.remove(
timer.
id,
false);
671 ETL_ENABLE_TIMER_UPDATES;
688 timer_array[id_].period = period_;
698 bool set_mode(etl::timer::id::type id_,
bool repeating_)
702 timer_array[id_].repeating = repeating_;
715 : timer_array(timer_array_),
716 active_list(timer_array_),
718#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
719 process_semaphore(0),
721 registered_timers(0),
722 MAX_TIMERS(MAX_TIMERS_)
734 volatile bool enabled;
735#if defined(ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK)
737#if defined(ETL_TIMER_SEMAPHORE_TYPE)
738 typedef ETL_TIMER_SEMAPHORE_TYPE timer_semaphore_t;
741 typedef etl::atomic_uint16_t timer_semaphore_t;
743 #error No atomic type available
747 etl::timer_semaphore_t process_semaphore;
749 uint_least8_t registered_timers;
753 const uint_least8_t MAX_TIMERS;
759 template <const u
int_least8_t MAX_TIMERS_>
764 ETL_STATIC_ASSERT(MAX_TIMERS_ <= 254,
"No more than 254 timers are allowed");
780#undef ETL_DISABLE_TIMER_UPDATES
781#undef ETL_ENABLE_TIMER_UPDATES
782#undef ETL_TIMER_UPDATES_ENABLED
The callback timer.
Definition: callback_timer.h:761
callback_timer()
Constructor.
Definition: callback_timer.h:769
Declaration.
Definition: delegate_cpp03.h:175
Interface for callback timer.
Definition: callback_timer.h:379
bool unregister_timer(etl::timer::id::type id_)
Register a timer.
Definition: callback_timer.h:485
bool is_running() const
Get the enable/disable state.
Definition: callback_timer.h:524
bool set_period(etl::timer::id::type id_, uint32_t period_)
Sets a timer's period.
Definition: callback_timer.h:684
etl::timer::id::type register_timer(void(*p_callback_)(), uint32_t period_, bool repeating_)
Register a timer.
Definition: callback_timer.h:387
bool start(etl::timer::id::type id_, bool immediate_=false)
Starts a timer.
Definition: callback_timer.h:619
icallback_timer(callback_timer_data *const timer_array_, const uint_least8_t MAX_TIMERS_)
Constructor.
Definition: callback_timer.h:714
bool set_mode(etl::timer::id::type id_, bool repeating_)
Sets a timer's mode.
Definition: callback_timer.h:698
bool stop(etl::timer::id::type id_)
Stops a timer.
Definition: callback_timer.h:655
void enable(bool state_)
Enable/disable the timer.
Definition: callback_timer.h:516
etl::timer::id::type register_timer(etl::ifunction< void > &callback_, uint32_t period_, bool repeating_)
Register a timer.
Definition: callback_timer.h:419
void clear()
Clears the timer of data.
Definition: callback_timer.h:532
A specialised intrusive linked list for timer data.
Definition: callback_timer.h:200
Definition: function.h:73
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:165
void set_inactive()
Sets the timer to the inactive state.
Definition: callback_timer.h:173
Common definitions for the timer framework.
Definition: timer.h:55