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  CallbackTimerApi() = default;
37 
39 
40  String name() const
41  {
42  String s;
43  s += typeName();
44  s += '@';
45  s += String(uintptr_t(this), HEX);
46  return s;
47  }
48 
49  String toString() const
50  {
51  String s;
52  s += name();
53  s += ": interval = ";
54  s += static_cast<const ApiDef*>(this)->getInterval();
55  s += ", ticks = ";
56  s += static_cast<const ApiDef*>(this)->ticks();
57  return s;
58  }
59 
60  operator String() const
61  {
62  return toString();
63  }
64 };
65 
73 template <typename TimerApi> class CallbackTimer : protected TimerApi
74 {
75 public:
76  using typename TimerApi::Clock;
77  using typename TimerApi::TickType;
78  using typename TimerApi::TimeType;
81 
82  using TimerApi::maxTicks;
83  using TimerApi::minTicks;
84  using TimerApi::toString;
85  using TimerApi::typeName;
86  using TimerApi::operator String;
87 
89  static constexpr Millis millis()
90  {
91  return Millis();
92  }
93 
95  static constexpr Micros micros()
96  {
97  return Micros();
98  }
99 
101  template <uint64_t us> static constexpr uint64_t usToTicks()
102  {
103  return Micros::template timeToTicks<us>();
104  }
105 
107  static TickType usToTicks(TimeType time)
108  {
109  return Micros::timeToTicks(time);
110  }
111 
113  template <uint64_t ticks> static constexpr uint64_t ticksToUs()
114  {
115  return Micros::template ticksToTime<ticks>();
116  }
117 
119  static TimeType ticksToUs(TickType ticks)
120  {
121  return Micros::ticksToTime(ticks);
122  }
123 
132  template <NanoTime::Unit unit, TimeType time>
133  CallbackTimer& IRAM_ATTR initialize(TimerCallback callback, void* arg = nullptr)
134  {
135  setCallback(callback, arg);
136  setInterval<unit, time>();
137  return *this;
138  }
139 
147  template <NanoTime::Unit unit>
148  CallbackTimer& IRAM_ATTR initialize(TimeType time, TimerCallback callback, void* arg = nullptr)
149  {
150  setCallback(callback, arg);
151  setInterval<unit>(time);
152  return *this;
153  }
154 
156  template <TimeType microseconds>
157  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimerCallback callback, void* arg = nullptr)
158  {
159  return initialize<NanoTime::Microseconds, microseconds>(callback, arg);
160  }
161 
163  template <TimeType microseconds>
164  __forceinline CallbackTimer& IRAM_ATTR initializeUs(InterruptCallback callback = nullptr)
165  {
166  return initializeUs<microseconds>(TimerCallback(callback));
167  }
168 
170  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, TimerCallback callback,
171  void* arg = nullptr)
172  {
173  return initialize<NanoTime::Microseconds>(microseconds, callback, arg);
174  }
175 
177  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, InterruptCallback callback = nullptr)
178  {
179  return initializeUs(microseconds, TimerCallback(callback));
180  }
181 
183  template <uint32_t milliseconds>
184  __forceinline CallbackTimer& IRAM_ATTR initializeMs(TimerCallback callback, void* arg = nullptr)
185  {
186  return initialize<NanoTime::Milliseconds, milliseconds>(callback, arg);
187  }
188 
190  template <uint32_t milliseconds>
191  __forceinline CallbackTimer& IRAM_ATTR initializeMs(InterruptCallback callback = nullptr)
192  {
193  return initializeMs<milliseconds>(TimerCallback(callback));
194  }
195 
197  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, TimerCallback callback,
198  void* arg = nullptr)
199  {
200  return initialize<NanoTime::Milliseconds>(milliseconds, callback, arg);
201  }
202 
204  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, InterruptCallback callback = nullptr)
205  {
206  return initializeMs(milliseconds, TimerCallback(callback));
207  }
208 
213  __forceinline bool IRAM_ATTR start(bool repeating = true)
214  {
215  stop();
216  if(!callbackSet || !intervalSet) {
217  return false;
218  }
219 
220  TimerApi::arm(repeating);
221  started = true;
222  this->repeating = repeating;
223  return true;
224  }
225 
230  __forceinline bool IRAM_ATTR startOnce()
231  {
232  return start(false);
233  }
234 
237  __forceinline void IRAM_ATTR stop()
238  {
239  if(started) {
240  TimerApi::disarm();
241  started = false;
242  }
243  }
244 
249  __forceinline bool IRAM_ATTR restart()
250  {
251  return start(repeating);
252  }
253 
257  __forceinline bool isStarted() const
258  {
259  return started;
260  }
261 
264  {
266  }
267 
270  {
272  }
273 
275  __forceinline TickType getInterval() const
276  {
277  return TimerApi::getInterval();
278  }
279 
284  bool IRAM_ATTR checkInterval(TickType ticks) const
285  {
286  return ticks >= minTicks() && ticks <= maxTicks();
287  }
288 
293  template <uint64_t ticks> static constexpr void checkInterval()
294  {
295  static_assert(ticks >= minTicks() && ticks <= maxTicks(), "Timer interval out of range");
296  }
297 
303  template <NanoTime::Unit unit, uint64_t time> static constexpr void checkInterval()
304  {
305  checkInterval<Clock::template TimeConst<unit, time>::ticks()>();
306  }
307 
309  template <uint64_t milliseconds> static constexpr void checkIntervalMs()
310  {
311  checkInterval<NanoTime::Milliseconds, milliseconds>();
312  }
313 
315  template <uint64_t microseconds> static constexpr void checkIntervalUs()
316  {
317  checkInterval<NanoTime::Microseconds, microseconds>();
318  }
319 
323  __forceinline bool IRAM_ATTR setInterval(TickType ticks)
324  {
325  if(checkInterval(ticks)) {
326  internalSetInterval(ticks);
327  } else {
328  stop();
329  intervalSet = false;
330  }
331  return started;
332  }
333 
338  template <TimeType ticks> __forceinline void IRAM_ATTR setInterval()
339  {
340  checkInterval<ticks>();
341  internalSetInterval(ticks);
342  }
343 
349  template <NanoTime::Unit unit, TimeType time> __forceinline void IRAM_ATTR setInterval()
350  {
351  setInterval<Clock::template TimeConst<unit, time>::ticks()>();
352  }
353 
358  template <NanoTime::Unit unit> __forceinline bool IRAM_ATTR setInterval(TimeType time)
359  {
360  return setInterval(Clock::template timeToTicks<unit>(time));
361  }
362 
364  __forceinline bool IRAM_ATTR setIntervalUs(TimeType microseconds)
365  {
366  return setInterval<NanoTime::Microseconds>(microseconds);
367  }
368 
370  template <TimeType microseconds> __forceinline void IRAM_ATTR setIntervalUs()
371  {
372  return setInterval<NanoTime::Microseconds, microseconds>();
373  }
374 
376  __forceinline bool IRAM_ATTR setIntervalMs(uint32_t milliseconds)
377  {
378  return setInterval<NanoTime::Milliseconds>(milliseconds);
379  }
380 
382  template <uint32_t milliseconds> __forceinline void IRAM_ATTR setIntervalMs()
383  {
384  return setInterval<NanoTime::Milliseconds, milliseconds>();
385  }
386 
391  __forceinline void IRAM_ATTR setCallback(TimerCallback callback, void* arg = nullptr)
392  {
393  // Always disarm before setting the callback
394  stop();
395  TimerApi::setCallback(callback, arg);
396  callbackSet = (callback != nullptr);
397  }
398 
404  __forceinline void IRAM_ATTR setCallback(InterruptCallback callback)
405  {
406  setCallback(reinterpret_cast<TimerCallback>(callback), nullptr);
407  }
408 
409 private:
410  __forceinline void IRAM_ATTR internalSetInterval(TickType ticks)
411  {
412  TimerApi::disarm();
413  TimerApi::setInterval(ticks);
414  intervalSet = true;
415  if(started) {
416  TimerApi::arm(repeating);
417  }
418  }
419 
420 protected:
421  bool callbackSet = false;
422  bool intervalSet = false;
423  bool repeating = false;
424  bool started = false;
425 };
426 
std::enable_if< std::is_integral< T >::value, String >::type toString(T value)
Definition: BitSet.h:481
#define HEX
Definition: WConstants.h:68
Callback timer class template.
Definition: CallbackTimer.h:74
void setInterval()
Set timer interval in specific time unit (static check)
Definition: CallbackTimer.h:349
CallbackTimer & initializeUs(TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:157
bool checkInterval(TickType ticks) const
Check timer interval is valid.
Definition: CallbackTimer.h:284
CallbackTimer & initializeMs(TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:184
NanoTime::Time< TimeType > getIntervalUs() const
Get timer interval in microseconds.
Definition: CallbackTimer.h:263
static constexpr void checkIntervalMs()
Check timer interval in milliseconds is valid (static check)
Definition: CallbackTimer.h:309
static TickType usToTicks(TimeType time)
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:107
bool setIntervalMs(uint32_t milliseconds)
Set timer interval in milliseconds.
Definition: CallbackTimer.h:376
void stop()
Stops timer.
Definition: CallbackTimer.h:237
static constexpr Millis millis()
Get a millisecond time source.
Definition: CallbackTimer.h:89
bool repeating
Timer is auto-repeat.
Definition: CallbackTimer.h:423
NanoTime::TimeSource< Clock, NanoTime::Microseconds, TimeType > Micros
Definition: CallbackTimer.h:80
void setCallback(InterruptCallback callback)
Set timer trigger callback.
Definition: CallbackTimer.h:404
static constexpr uint64_t ticksToUs()
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:113
static constexpr void checkInterval()
Check timer interval in specific time unit is valid (static check)
Definition: CallbackTimer.h:303
CallbackTimer & initializeMs(InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds (static check) and optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:191
bool setIntervalUs(TimeType microseconds)
Set timer interval in microseconds.
Definition: CallbackTimer.h:364
CallbackTimer & initializeUs(TimeType microseconds, TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:170
CallbackTimer & initializeUs(InterruptCallback callback=nullptr)
Initialise timer in microseconds (static check) with optional Interrupt Callback (no argument)
Definition: CallbackTimer.h:164
bool callbackSet
User has provided callback function.
Definition: CallbackTimer.h:421
void setIntervalUs()
Set timer interval in microseconds (static check)
Definition: CallbackTimer.h:370
NanoTime::Time< uint32_t > getIntervalMs() const
Get timer interval in milliseconds.
Definition: CallbackTimer.h:269
bool setInterval(TimeType time)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:358
void setIntervalMs()
Set timer interval in milliseconds (static check)
Definition: CallbackTimer.h:382
bool start(bool repeating=true)
Start timer running.
Definition: CallbackTimer.h:213
CallbackTimer & initializeUs(TimeType microseconds, InterruptCallback callback=nullptr)
Initialise timer in microseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:177
CallbackTimer & initializeMs(uint32_t milliseconds, TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:197
bool started
Timer is active, or has fired.
Definition: CallbackTimer.h:424
NanoTime::TimeSource< Clock, NanoTime::Milliseconds, uint32_t > Millis
Definition: CallbackTimer.h:79
CallbackTimer & initializeMs(uint32_t milliseconds, InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:204
CallbackTimer & initialize(TimeType time, TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval and callback.
Definition: CallbackTimer.h:148
static constexpr Micros micros()
Get a microsecond time source.
Definition: CallbackTimer.h:95
static constexpr uint64_t usToTicks()
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:101
TickType getInterval() const
Get timer interval in clock ticks.
Definition: CallbackTimer.h:275
static constexpr void checkInterval()
Check timer interval in ticks is valid (static check)
Definition: CallbackTimer.h:293
bool startOnce()
Start one-shot timer.
Definition: CallbackTimer.h:230
bool restart()
Restart timer.
Definition: CallbackTimer.h:249
static constexpr void checkIntervalUs()
Check timer interval in microseconds is valid (static check)
Definition: CallbackTimer.h:315
bool isStarted() const
Check if timer is started.
Definition: CallbackTimer.h:257
void setInterval()
Set timer interval in timer ticks (static check)
Definition: CallbackTimer.h:338
static TimeType ticksToUs(TickType ticks)
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:119
bool setInterval(TickType ticks)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:323
bool intervalSet
User has set valid time interval.
Definition: CallbackTimer.h:422
CallbackTimer & initialize(TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval (static check) and callback.
Definition: CallbackTimer.h:133
void setCallback(TimerCallback callback, void *arg=nullptr)
Set timer trigger callback.
Definition: CallbackTimer.h:391
The String class.
Definition: WString.h:133
void(*)(void *arg) TimerCallback
Interrupt-compatible C callback function pointer.
Definition: CallbackTimer.h:23
void(*)() InterruptCallback
Definition: Interrupts.h:23
void setCallback(Callback callback)
Set a callback function that is invoked on each change of the current allocation.
Time< T > time(Unit unit, T value)
Helper function to create a Time and deduce the type.
Definition: NanoTime.h:432
Callback timer API class template.
Definition: CallbackTimer.h:30
String toString() const
Definition: CallbackTimer.h:49
String name() const
Definition: CallbackTimer.h:40
static constexpr const char * typeName()
Definition: CallbackTimer.h:31
CallbackTimerApi()=default
CallbackTimerApi(const CallbackTimerApi &)=delete
Class template for accessing a Clock in specific time units.
Definition: NanoTime.h:639
static constexpr uint64_t ticksToTime()
Get the time for a given number of clock ticks.
Definition: NanoTime.h:737
static constexpr uint64_t timeToTicks()
Get the number of ticks for a given time.
Definition: NanoTime.h:727
Class to handle a simple time value with associated unit.
Definition: NanoTime.h:373