CallbackTimer.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * CallbackTimer.h - Template classes to implement callback timers
8  *
9  ****/
10 
11 #pragma once
12 
13 #include "Interrupts.h"
14 #include "NanoTime.h"
15 
23 using TimerCallback = void (*)(void* arg);
24 using TimerDelegate = Delegate<void()>;
25 
30 template <typename ApiDef> struct CallbackTimerApi {
31  static constexpr const char* typeName()
32  {
33  return ApiDef::typeName();
34  }
35 
36  String name() const
37  {
38  String s;
39  s += typeName();
40  s += '@';
41  s += String(uint32_t(this), HEX);
42  return s;
43  }
44 
45  String toString() const
46  {
47  String s;
48  s += name();
49  s += ": interval = ";
50  s += static_cast<const ApiDef*>(this)->getInterval();
51  s += ", ticks = ";
52  s += static_cast<const ApiDef*>(this)->ticks();
53  // s += ApiDef::Clock::ticks();
54  return s;
55  }
56 
57  operator String() const
58  {
59  return toString();
60  }
61 };
62 
70 template <typename TimerApi> class CallbackTimer : protected TimerApi
71 {
72 public:
73  using typename TimerApi::Clock;
74  using typename TimerApi::TickType;
75  using typename TimerApi::TimeType;
78 
79  using TimerApi::maxTicks;
80  using TimerApi::minTicks;
81  using TimerApi::toString;
82  using TimerApi::typeName;
83  using TimerApi::operator String;
84 
86  static constexpr Millis millis()
87  {
88  return Millis();
89  }
90 
92  static constexpr Micros micros()
93  {
94  return Micros();
95  }
96 
98  template <uint64_t us> static constexpr uint64_t usToTicks()
99  {
100  return Micros::template timeToTicks<us>();
101  }
102 
105  {
106  return Micros::timeToTicks(time);
107  }
108 
110  template <uint64_t ticks> static constexpr uint64_t ticksToUs()
111  {
112  return Micros::template ticksToTime<ticks>();
113  }
114 
117  {
118  return Micros::ticksToTime(ticks);
119  }
120 
129  template <NanoTime::Unit unit, TimeType time>
130  CallbackTimer& IRAM_ATTR initialize(TimerCallback callback, void* arg = nullptr)
131  {
132  setCallback(callback, arg);
133  setInterval<unit, time>();
134  return *this;
135  }
136 
144  template <NanoTime::Unit unit>
145  CallbackTimer& IRAM_ATTR initialize(TimeType time, TimerCallback callback, void* arg = nullptr)
146  {
147  setCallback(callback, arg);
148  setInterval<unit>(time);
149  return *this;
150  }
151 
153  template <TimeType microseconds>
154  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimerCallback callback, void* arg = nullptr)
155  {
156  return initialize<NanoTime::Microseconds, microseconds>(callback, arg);
157  }
158 
160  template <TimeType microseconds>
161  __forceinline CallbackTimer& IRAM_ATTR initializeUs(InterruptCallback callback = nullptr)
162  {
163  return initializeUs<microseconds>(TimerCallback(callback));
164  }
165 
167  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, TimerCallback callback,
168  void* arg = nullptr)
169  {
170  return initialize<NanoTime::Microseconds>(microseconds, callback, arg);
171  }
172 
174  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, InterruptCallback callback = nullptr)
175  {
176  return initializeUs(microseconds, TimerCallback(callback));
177  }
178 
180  template <uint32_t milliseconds>
181  __forceinline CallbackTimer& IRAM_ATTR initializeMs(TimerCallback callback, void* arg = nullptr)
182  {
183  return initialize<NanoTime::Milliseconds, milliseconds>(callback, arg);
184  }
185 
187  template <uint32_t milliseconds>
188  __forceinline CallbackTimer& IRAM_ATTR initializeMs(InterruptCallback callback = nullptr)
189  {
190  return initializeMs<milliseconds>(TimerCallback(callback));
191  }
192 
194  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, TimerCallback callback,
195  void* arg = nullptr)
196  {
197  return initialize<NanoTime::Milliseconds>(milliseconds, callback, arg);
198  }
199 
201  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, InterruptCallback callback = nullptr)
202  {
203  return initializeMs(milliseconds, TimerCallback(callback));
204  }
205 
210  __forceinline bool IRAM_ATTR start(bool repeating = true)
211  {
212  stop();
213  if(!callbackSet || !intervalSet) {
214  return false;
215  }
216 
217  TimerApi::arm(repeating);
218  started = true;
219  this->repeating = repeating;
220  return true;
221  }
222 
227  __forceinline bool IRAM_ATTR startOnce()
228  {
229  return start(false);
230  }
231 
234  __forceinline void IRAM_ATTR stop()
235  {
236  if(started) {
237  TimerApi::disarm();
238  started = false;
239  }
240  }
241 
246  __forceinline bool IRAM_ATTR restart()
247  {
248  return start(repeating);
249  }
250 
254  __forceinline bool isStarted() const
255  {
256  return started;
257  }
258 
261  {
263  }
264 
267  {
269  }
270 
272  __forceinline TickType getInterval() const
273  {
274  return TimerApi::getInterval();
275  }
276 
281  bool IRAM_ATTR checkInterval(TickType ticks) const
282  {
283  return ticks >= minTicks() && ticks <= maxTicks();
284  }
285 
290  template <uint64_t ticks> static constexpr void checkInterval()
291  {
292  static_assert(ticks >= minTicks() && ticks <= maxTicks(), "Timer interval out of range");
293  }
294 
300  template <NanoTime::Unit unit, uint64_t time> static constexpr void checkInterval()
301  {
302  checkInterval<Clock::template TimeConst<unit, time>::ticks()>();
303  }
304 
306  template <uint64_t milliseconds> static constexpr void checkIntervalMs()
307  {
308  checkInterval<NanoTime::Milliseconds, milliseconds>();
309  }
310 
312  template <uint64_t microseconds> static constexpr void checkIntervalUs()
313  {
314  checkInterval<NanoTime::Microseconds, microseconds>();
315  }
316 
320  __forceinline bool IRAM_ATTR setInterval(TickType ticks)
321  {
322  if(checkInterval(ticks)) {
323  internalSetInterval(ticks);
324  } else {
325  stop();
326  intervalSet = false;
327  }
328  return started;
329  }
330 
335  template <TimeType ticks> __forceinline void IRAM_ATTR setInterval()
336  {
337  checkInterval<ticks>();
338  internalSetInterval(ticks);
339  }
340 
346  template <NanoTime::Unit unit, TimeType time> __forceinline void IRAM_ATTR setInterval()
347  {
348  setInterval<Clock::template TimeConst<unit, time>::ticks()>();
349  }
350 
355  template <NanoTime::Unit unit> __forceinline bool IRAM_ATTR setInterval(TimeType time)
356  {
357  return setInterval(Clock::template timeToTicks<unit>(time));
358  }
359 
361  __forceinline bool IRAM_ATTR setIntervalUs(TimeType microseconds)
362  {
363  return setInterval<NanoTime::Microseconds>(microseconds);
364  }
365 
367  template <TimeType microseconds> __forceinline void IRAM_ATTR setIntervalUs()
368  {
369  return setInterval<NanoTime::Microseconds, microseconds>();
370  }
371 
373  __forceinline bool IRAM_ATTR setIntervalMs(uint32_t milliseconds)
374  {
375  return setInterval<NanoTime::Milliseconds>(milliseconds);
376  }
377 
379  template <uint32_t milliseconds> __forceinline void IRAM_ATTR setIntervalMs()
380  {
381  return setInterval<NanoTime::Milliseconds, milliseconds>();
382  }
383 
388  __forceinline void IRAM_ATTR setCallback(TimerCallback callback, void* arg = nullptr)
389  {
390  // Always disarm before setting the callback
391  stop();
392  TimerApi::setCallback(callback, arg);
393  callbackSet = (callback != nullptr);
394  }
395 
401  __forceinline void IRAM_ATTR setCallback(InterruptCallback callback)
402  {
403  setCallback(reinterpret_cast<TimerCallback>(callback), nullptr);
404  }
405 
406 private:
407  __forceinline void IRAM_ATTR internalSetInterval(TickType ticks)
408  {
409  TimerApi::disarm();
410  TimerApi::setInterval(ticks);
411  intervalSet = true;
412  if(started) {
413  TimerApi::arm(repeating);
414  }
415  }
416 
417 protected:
418  bool callbackSet = false;
419  bool intervalSet = false;
420  bool repeating = false;
421  bool started = false;
422 };
423 
Class template for accessing a Clock in specific time units.
Definition: NanoTime.h:122
void(*)(void *arg) TimerCallback
Interrupt-compatible C callback function pointer.
Definition: CallbackTimer.h:23
static TimeType ticksToUs(TickType ticks)
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:116
void(*)() InterruptCallback
Definition: Interrupts.h:23
static constexpr void checkIntervalMs()
Check timer interval in milliseconds is valid (static check)
Definition: CallbackTimer.h:306
Callback timer class template.
Definition: CallbackTimer.h:70
TickType getInterval() const
Get timer interval in clock ticks.
Definition: CallbackTimer.h:272
bool start(bool repeating=true)
Start timer running.
Definition: CallbackTimer.h:210
bool checkInterval(TickType ticks) const
Check timer interval is valid.
Definition: CallbackTimer.h:281
static constexpr Millis millis()
Get a millisecond time source.
Definition: CallbackTimer.h:86
String name() const
Definition: CallbackTimer.h:36
CallbackTimer & initializeMs(uint32_t milliseconds, TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:194
Time< T > time(Unit unit, T value)
Helper function to create a Time and deduce the type.
Definition: NanoTime.h:429
static TickType usToTicks(TimeType time)
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:104
NanoTime::TimeSource< Clock, NanoTime::Microseconds, TimeType > Micros
Definition: CallbackTimer.h:77
void setCallback(Callback callback)
Set a callback function that is invoked on each change of the current allocation.
uint64_t TickType
Definition: Timer.h:30
bool startOnce()
Start one-shot timer.
Definition: CallbackTimer.h:227
bool started
Timer is active, or has fired.
Definition: CallbackTimer.h:421
CallbackTimer & initializeMs(TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:181
The String class.
Definition: WString.h:136
static constexpr void checkInterval()
Check timer interval in ticks is valid (static check)
Definition: CallbackTimer.h:290
bool callbackSet
User has provided callback function.
Definition: CallbackTimer.h:418
static constexpr uint64_t ticksToUs()
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:110
CallbackTimer & initializeUs(TimeType microseconds, TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:167
bool repeating
Timer is auto-repeat.
Definition: CallbackTimer.h:420
void setInterval()
Set timer interval in timer ticks (static check)
Definition: CallbackTimer.h:335
CallbackTimer & initializeMs(InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds (static check) and optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:188
static constexpr void checkIntervalUs()
Check timer interval in microseconds is valid (static check)
Definition: CallbackTimer.h:312
Class to handle a simple time value with associated unit.
Definition: NanoTime.h:123
std::enable_if< std::is_integral< T >::value, String >::type toString(T value)
Definition: BitSet.h:481
bool setInterval(TimeType time)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:355
CallbackTimer & initializeUs(TimeType microseconds, InterruptCallback callback=nullptr)
Initialise timer in microseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:174
void setCallback(InterruptCallback callback)
Set timer trigger callback.
Definition: CallbackTimer.h:401
bool restart()
Restart timer.
Definition: CallbackTimer.h:246
NanoTime::Time< TimeType > getIntervalUs() const
Get timer interval in microseconds.
Definition: CallbackTimer.h:260
bool setIntervalUs(TimeType microseconds)
Set timer interval in microseconds.
Definition: CallbackTimer.h:361
uint64_t TimeType
Definition: Timer.h:31
CallbackTimer & initializeMs(uint32_t milliseconds, InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:201
static constexpr uint64_t ticksToTime()
Get the time for a given number of clock ticks.
Definition: NanoTime.h:734
static constexpr const char * typeName()
Definition: CallbackTimer.h:31
static constexpr Micros micros()
Get a microsecond time source.
Definition: CallbackTimer.h:92
static constexpr uint64_t timeToTicks()
Get the number of ticks for a given time.
Definition: NanoTime.h:724
void setIntervalMs()
Set timer interval in milliseconds (static check)
Definition: CallbackTimer.h:379
CallbackTimer & initializeUs(InterruptCallback callback=nullptr)
Initialise timer in microseconds (static check) with optional Interrupt Callback (no argument)
Definition: CallbackTimer.h:161
String toString() const
Definition: CallbackTimer.h:45
NanoTime::TimeSource< Clock, NanoTime::Milliseconds, uint32_t > Millis
Definition: CallbackTimer.h:76
Callback timer API class template.
Definition: CallbackTimer.h:30
void setCallback(TimerCallback callback, void *arg=nullptr)
Set timer trigger callback.
Definition: CallbackTimer.h:388
void stop()
Stops timer.
Definition: CallbackTimer.h:234
void setInterval()
Set timer interval in specific time unit (static check)
Definition: CallbackTimer.h:346
static constexpr void checkInterval()
Check timer interval in specific time unit is valid (static check)
Definition: CallbackTimer.h:300
void setIntervalUs()
Set timer interval in microseconds (static check)
Definition: CallbackTimer.h:367
bool isStarted() const
Check if timer is started.
Definition: CallbackTimer.h:254
CallbackTimer & initialize(TimeType time, TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval and callback.
Definition: CallbackTimer.h:145
CallbackTimer & initializeUs(TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:154
NanoTime::Time< uint32_t > getIntervalMs() const
Get timer interval in milliseconds.
Definition: CallbackTimer.h:266
static constexpr uint64_t usToTicks()
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:98
bool setInterval(TickType ticks)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:320
bool setIntervalMs(uint32_t milliseconds)
Set timer interval in milliseconds.
Definition: CallbackTimer.h:373
CallbackTimer & initialize(TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval (static check) and callback.
Definition: CallbackTimer.h:130
#define HEX
Definition: WConstants.h:68
bool intervalSet
User has set valid time interval.
Definition: CallbackTimer.h:419