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 
37  {
38  }
39 
41 
42  String name() const
43  {
44  String s;
45  s += typeName();
46  s += '@';
47  s += String(uint32_t(this), HEX);
48  return s;
49  }
50 
51  String toString() const
52  {
53  String s;
54  s += name();
55  s += ": interval = ";
56  s += static_cast<const ApiDef*>(this)->getInterval();
57  s += ", ticks = ";
58  s += static_cast<const ApiDef*>(this)->ticks();
59  return s;
60  }
61 
62  operator String() const
63  {
64  return toString();
65  }
66 };
67 
75 template <typename TimerApi> class CallbackTimer : protected TimerApi
76 {
77 public:
78  using typename TimerApi::Clock;
79  using typename TimerApi::TickType;
80  using typename TimerApi::TimeType;
83 
84  using TimerApi::maxTicks;
85  using TimerApi::minTicks;
86  using TimerApi::toString;
87  using TimerApi::typeName;
88  using TimerApi::operator String;
89 
91  static constexpr Millis millis()
92  {
93  return Millis();
94  }
95 
97  static constexpr Micros micros()
98  {
99  return Micros();
100  }
101 
103  template <uint64_t us> static constexpr uint64_t usToTicks()
104  {
105  return Micros::template timeToTicks<us>();
106  }
107 
109  static TickType usToTicks(TimeType time)
110  {
111  return Micros::timeToTicks(time);
112  }
113 
115  template <uint64_t ticks> static constexpr uint64_t ticksToUs()
116  {
117  return Micros::template ticksToTime<ticks>();
118  }
119 
121  static TimeType ticksToUs(TickType ticks)
122  {
123  return Micros::ticksToTime(ticks);
124  }
125 
134  template <NanoTime::Unit unit, TimeType time>
135  CallbackTimer& IRAM_ATTR initialize(TimerCallback callback, void* arg = nullptr)
136  {
137  setCallback(callback, arg);
138  setInterval<unit, time>();
139  return *this;
140  }
141 
149  template <NanoTime::Unit unit>
150  CallbackTimer& IRAM_ATTR initialize(TimeType time, TimerCallback callback, void* arg = nullptr)
151  {
152  setCallback(callback, arg);
153  setInterval<unit>(time);
154  return *this;
155  }
156 
158  template <TimeType microseconds>
159  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimerCallback callback, void* arg = nullptr)
160  {
161  return initialize<NanoTime::Microseconds, microseconds>(callback, arg);
162  }
163 
165  template <TimeType microseconds>
166  __forceinline CallbackTimer& IRAM_ATTR initializeUs(InterruptCallback callback = nullptr)
167  {
168  return initializeUs<microseconds>(TimerCallback(callback));
169  }
170 
172  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, TimerCallback callback,
173  void* arg = nullptr)
174  {
175  return initialize<NanoTime::Microseconds>(microseconds, callback, arg);
176  }
177 
179  __forceinline CallbackTimer& IRAM_ATTR initializeUs(TimeType microseconds, InterruptCallback callback = nullptr)
180  {
181  return initializeUs(microseconds, TimerCallback(callback));
182  }
183 
185  template <uint32_t milliseconds>
186  __forceinline CallbackTimer& IRAM_ATTR initializeMs(TimerCallback callback, void* arg = nullptr)
187  {
188  return initialize<NanoTime::Milliseconds, milliseconds>(callback, arg);
189  }
190 
192  template <uint32_t milliseconds>
193  __forceinline CallbackTimer& IRAM_ATTR initializeMs(InterruptCallback callback = nullptr)
194  {
195  return initializeMs<milliseconds>(TimerCallback(callback));
196  }
197 
199  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, TimerCallback callback,
200  void* arg = nullptr)
201  {
202  return initialize<NanoTime::Milliseconds>(milliseconds, callback, arg);
203  }
204 
206  __forceinline CallbackTimer& IRAM_ATTR initializeMs(uint32_t milliseconds, InterruptCallback callback = nullptr)
207  {
208  return initializeMs(milliseconds, TimerCallback(callback));
209  }
210 
215  __forceinline bool IRAM_ATTR start(bool repeating = true)
216  {
217  stop();
218  if(!callbackSet || !intervalSet) {
219  return false;
220  }
221 
222  TimerApi::arm(repeating);
223  started = true;
224  this->repeating = repeating;
225  return true;
226  }
227 
232  __forceinline bool IRAM_ATTR startOnce()
233  {
234  return start(false);
235  }
236 
239  __forceinline void IRAM_ATTR stop()
240  {
241  if(started) {
242  TimerApi::disarm();
243  started = false;
244  }
245  }
246 
251  __forceinline bool IRAM_ATTR restart()
252  {
253  return start(repeating);
254  }
255 
259  __forceinline bool isStarted() const
260  {
261  return started;
262  }
263 
266  {
268  }
269 
272  {
274  }
275 
277  __forceinline TickType getInterval() const
278  {
279  return TimerApi::getInterval();
280  }
281 
286  bool IRAM_ATTR checkInterval(TickType ticks) const
287  {
288  return ticks >= minTicks() && ticks <= maxTicks();
289  }
290 
295  template <uint64_t ticks> static constexpr void checkInterval()
296  {
297  static_assert(ticks >= minTicks() && ticks <= maxTicks(), "Timer interval out of range");
298  }
299 
305  template <NanoTime::Unit unit, uint64_t time> static constexpr void checkInterval()
306  {
307  checkInterval<Clock::template TimeConst<unit, time>::ticks()>();
308  }
309 
311  template <uint64_t milliseconds> static constexpr void checkIntervalMs()
312  {
313  checkInterval<NanoTime::Milliseconds, milliseconds>();
314  }
315 
317  template <uint64_t microseconds> static constexpr void checkIntervalUs()
318  {
319  checkInterval<NanoTime::Microseconds, microseconds>();
320  }
321 
325  __forceinline bool IRAM_ATTR setInterval(TickType ticks)
326  {
327  if(checkInterval(ticks)) {
328  internalSetInterval(ticks);
329  } else {
330  stop();
331  intervalSet = false;
332  }
333  return started;
334  }
335 
340  template <TimeType ticks> __forceinline void IRAM_ATTR setInterval()
341  {
342  checkInterval<ticks>();
343  internalSetInterval(ticks);
344  }
345 
351  template <NanoTime::Unit unit, TimeType time> __forceinline void IRAM_ATTR setInterval()
352  {
353  setInterval<Clock::template TimeConst<unit, time>::ticks()>();
354  }
355 
360  template <NanoTime::Unit unit> __forceinline bool IRAM_ATTR setInterval(TimeType time)
361  {
362  return setInterval(Clock::template timeToTicks<unit>(time));
363  }
364 
366  __forceinline bool IRAM_ATTR setIntervalUs(TimeType microseconds)
367  {
368  return setInterval<NanoTime::Microseconds>(microseconds);
369  }
370 
372  template <TimeType microseconds> __forceinline void IRAM_ATTR setIntervalUs()
373  {
374  return setInterval<NanoTime::Microseconds, microseconds>();
375  }
376 
378  __forceinline bool IRAM_ATTR setIntervalMs(uint32_t milliseconds)
379  {
380  return setInterval<NanoTime::Milliseconds>(milliseconds);
381  }
382 
384  template <uint32_t milliseconds> __forceinline void IRAM_ATTR setIntervalMs()
385  {
386  return setInterval<NanoTime::Milliseconds, milliseconds>();
387  }
388 
393  __forceinline void IRAM_ATTR setCallback(TimerCallback callback, void* arg = nullptr)
394  {
395  // Always disarm before setting the callback
396  stop();
397  TimerApi::setCallback(callback, arg);
398  callbackSet = (callback != nullptr);
399  }
400 
406  __forceinline void IRAM_ATTR setCallback(InterruptCallback callback)
407  {
408  setCallback(reinterpret_cast<TimerCallback>(callback), nullptr);
409  }
410 
411 private:
412  __forceinline void IRAM_ATTR internalSetInterval(TickType ticks)
413  {
414  TimerApi::disarm();
415  TimerApi::setInterval(ticks);
416  intervalSet = true;
417  if(started) {
418  TimerApi::arm(repeating);
419  }
420  }
421 
422 protected:
423  bool callbackSet = false;
424  bool intervalSet = false;
425  bool repeating = false;
426  bool started = false;
427 };
428 
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:76
void setInterval()
Set timer interval in specific time unit (static check)
Definition: CallbackTimer.h:351
CallbackTimer & initializeUs(TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:159
bool checkInterval(TickType ticks) const
Check timer interval is valid.
Definition: CallbackTimer.h:286
CallbackTimer & initializeMs(TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:186
NanoTime::Time< TimeType > getIntervalUs() const
Get timer interval in microseconds.
Definition: CallbackTimer.h:265
static constexpr void checkIntervalMs()
Check timer interval in milliseconds is valid (static check)
Definition: CallbackTimer.h:311
static TickType usToTicks(TimeType time)
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:109
bool setIntervalMs(uint32_t milliseconds)
Set timer interval in milliseconds.
Definition: CallbackTimer.h:378
void stop()
Stops timer.
Definition: CallbackTimer.h:239
static constexpr Millis millis()
Get a millisecond time source.
Definition: CallbackTimer.h:91
bool repeating
Timer is auto-repeat.
Definition: CallbackTimer.h:425
NanoTime::TimeSource< Clock, NanoTime::Microseconds, TimeType > Micros
Definition: CallbackTimer.h:82
void setCallback(InterruptCallback callback)
Set timer trigger callback.
Definition: CallbackTimer.h:406
static constexpr uint64_t ticksToUs()
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:115
static constexpr void checkInterval()
Check timer interval in specific time unit is valid (static check)
Definition: CallbackTimer.h:305
CallbackTimer & initializeMs(InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds (static check) and optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:193
bool setIntervalUs(TimeType microseconds)
Set timer interval in microseconds.
Definition: CallbackTimer.h:366
CallbackTimer & initializeUs(TimeType microseconds, TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:172
CallbackTimer & initializeUs(InterruptCallback callback=nullptr)
Initialise timer in microseconds (static check) with optional Interrupt Callback (no argument)
Definition: CallbackTimer.h:166
bool callbackSet
User has provided callback function.
Definition: CallbackTimer.h:423
void setIntervalUs()
Set timer interval in microseconds (static check)
Definition: CallbackTimer.h:372
NanoTime::Time< uint32_t > getIntervalMs() const
Get timer interval in milliseconds.
Definition: CallbackTimer.h:271
bool setInterval(TimeType time)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:360
void setIntervalMs()
Set timer interval in milliseconds (static check)
Definition: CallbackTimer.h:384
bool start(bool repeating=true)
Start timer running.
Definition: CallbackTimer.h:215
CallbackTimer & initializeUs(TimeType microseconds, InterruptCallback callback=nullptr)
Initialise timer in microseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:179
CallbackTimer & initializeMs(uint32_t milliseconds, TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:199
bool started
Timer is active, or has fired.
Definition: CallbackTimer.h:426
NanoTime::TimeSource< Clock, NanoTime::Milliseconds, uint32_t > Millis
Definition: CallbackTimer.h:81
CallbackTimer & initializeMs(uint32_t milliseconds, InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:206
CallbackTimer & initialize(TimeType time, TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval and callback.
Definition: CallbackTimer.h:150
static constexpr Micros micros()
Get a microsecond time source.
Definition: CallbackTimer.h:97
static constexpr uint64_t usToTicks()
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:103
TickType getInterval() const
Get timer interval in clock ticks.
Definition: CallbackTimer.h:277
static constexpr void checkInterval()
Check timer interval in ticks is valid (static check)
Definition: CallbackTimer.h:295
bool startOnce()
Start one-shot timer.
Definition: CallbackTimer.h:232
bool restart()
Restart timer.
Definition: CallbackTimer.h:251
static constexpr void checkIntervalUs()
Check timer interval in microseconds is valid (static check)
Definition: CallbackTimer.h:317
bool isStarted() const
Check if timer is started.
Definition: CallbackTimer.h:259
void setInterval()
Set timer interval in timer ticks (static check)
Definition: CallbackTimer.h:340
static TimeType ticksToUs(TickType ticks)
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:121
bool setInterval(TickType ticks)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:325
bool intervalSet
User has set valid time interval.
Definition: CallbackTimer.h:424
CallbackTimer & initialize(TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval (static check) and callback.
Definition: CallbackTimer.h:135
void setCallback(TimerCallback callback, void *arg=nullptr)
Set timer trigger callback.
Definition: CallbackTimer.h:393
The String class.
Definition: WString.h:137
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:423
Callback timer API class template.
Definition: CallbackTimer.h:30
CallbackTimerApi()
Definition: CallbackTimer.h:36
String toString() const
Definition: CallbackTimer.h:51
String name() const
Definition: CallbackTimer.h:42
static constexpr const char * typeName()
Definition: CallbackTimer.h:31
CallbackTimerApi(const CallbackTimerApi &)=delete
Class template for accessing a Clock in specific time units.
Definition: NanoTime.h:630
static constexpr uint64_t ticksToTime()
Get the time for a given number of clock ticks.
Definition: NanoTime.h:728
static constexpr uint64_t timeToTicks()
Get the number of ticks for a given time.
Definition: NanoTime.h:718
Class to handle a simple time value with associated unit.
Definition: NanoTime.h:364