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 typedef void (*TimerCallback)(void* arg);
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>
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>
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  IRAM_ATTR bool start(bool repeating = true);
211 
216  __forceinline bool IRAM_ATTR startOnce()
217  {
218  return start(false);
219  }
220 
223  __forceinline void IRAM_ATTR stop()
224  {
225  if(started) {
226  TimerApi::disarm();
227  started = false;
228  }
229  }
230 
235  __forceinline bool IRAM_ATTR restart()
236  {
237  return start(repeating);
238  }
239 
244  {
245  return started;
246  }
247 
250  {
251  return Micros::ticksToTime(getInterval());
252  }
253 
256  {
257  return Millis::ticksToTime(getInterval());
258  }
259 
262  {
263  return TimerApi::getInterval();
264  }
265 
270  bool IRAM_ATTR checkInterval(TickType ticks) const
271  {
272  return ticks >= minTicks() && ticks <= maxTicks();
273  }
274 
279  template <uint64_t ticks> static constexpr void checkInterval()
280  {
281  static_assert(ticks >= minTicks() && ticks <= maxTicks(), "Timer interval out of range");
282  }
283 
289  template <NanoTime::Unit unit, uint64_t time> static constexpr void checkInterval()
290  {
291  checkInterval<Clock::template TimeConst<unit, time>::ticks()>();
292  }
293 
295  template <uint64_t milliseconds> static constexpr void checkIntervalMs()
296  {
297  checkInterval<NanoTime::Milliseconds, milliseconds>();
298  }
299 
301  template <uint64_t microseconds> static constexpr void checkIntervalUs()
302  {
303  checkInterval<NanoTime::Microseconds, microseconds>();
304  }
305 
309  __forceinline bool IRAM_ATTR setInterval(TickType ticks)
310  {
311  if(checkInterval(ticks)) {
312  internalSetInterval(ticks);
313  } else {
314  stop();
315  intervalSet = false;
316  }
317  return started;
318  }
319 
324  template <TimeType ticks> __forceinline void IRAM_ATTR setInterval()
325  {
326  checkInterval<ticks>();
327  internalSetInterval(ticks);
328  }
329 
335  template <NanoTime::Unit unit, TimeType time> __forceinline void IRAM_ATTR setInterval()
336  {
337  setInterval<Clock::template TimeConst<unit, time>::ticks()>();
338  }
339 
344  template <NanoTime::Unit unit> __forceinline bool IRAM_ATTR setInterval(TimeType time)
345  {
346  return setInterval(Clock::template timeToTicks<unit>(time));
347  }
348 
350  __forceinline bool IRAM_ATTR setIntervalUs(TimeType microseconds)
351  {
352  return setInterval<NanoTime::Microseconds>(microseconds);
353  }
354 
356  template <TimeType microseconds> __forceinline void IRAM_ATTR setIntervalUs()
357  {
358  return setInterval<NanoTime::Microseconds, microseconds>();
359  }
360 
362  __forceinline bool IRAM_ATTR setIntervalMs(uint32_t milliseconds)
363  {
364  return setInterval<NanoTime::Milliseconds>(milliseconds);
365  }
366 
368  template <uint32_t milliseconds> __forceinline void IRAM_ATTR setIntervalMs()
369  {
370  return setInterval<NanoTime::Milliseconds, milliseconds>();
371  }
372 
377  __forceinline void IRAM_ATTR setCallback(TimerCallback callback, void* arg = nullptr)
378  {
379  // Always disarm before setting the callback
380  stop();
381  TimerApi::setCallback(callback, arg);
382  callbackSet = (callback != nullptr);
383  }
384 
390  __forceinline void IRAM_ATTR setCallback(InterruptCallback callback)
391  {
392  setCallback(reinterpret_cast<TimerCallback>(callback), nullptr);
393  }
394 
395 private:
396  __forceinline void IRAM_ATTR internalSetInterval(TickType ticks)
397  {
398  TimerApi::disarm();
399  TimerApi::setInterval(ticks);
400  intervalSet = true;
401  if(started) {
402  TimerApi::arm(repeating);
403  }
404  }
405 
406 protected:
407  bool callbackSet = false;
408  bool intervalSet = false;
409  bool repeating = false;
410  bool started = false;
411 };
412 
413 template <typename TimerApi> IRAM_ATTR bool CallbackTimer<TimerApi>::start(bool repeating)
414 {
415  stop();
416  if(!callbackSet || !intervalSet) {
417  return false;
418  }
419 
420  TimerApi::arm(repeating);
421  started = true;
422  this->repeating = repeating;
423  return true;
424 }
425 
static TickType usToTicks(TimeType time)
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:104
#define __forceinline
Definition: sming_attr.h:13
uint64_t TickType
Definition: Timer.h:33
bool setInterval(TickType ticks)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:309
bool setIntervalMs(uint32_t milliseconds)
Set timer interval in milliseconds.
Definition: CallbackTimer.h:362
static TimeType ticksToUs(TickType ticks)
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:116
CallbackTimer & initializeMs(InterruptCallback callback=nullptr)
Initialise hardware timer in milliseconds (static check) and optional Interrupt Callback (no arg) ...
Definition: CallbackTimer.h:188
void setIntervalUs()
Set timer interval in microseconds (static check)
Definition: CallbackTimer.h:356
void(* InterruptCallback)()
Definition: Interrupts.h:25
String name() const
Definition: CallbackTimer.h:36
#define HEX
Definition: WConstants.h:66
CallbackTimer & initialize(TimeType time, TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval and callback.
Definition: CallbackTimer.h:145
uint64_t TimeType
Definition: Timer.h:34
static constexpr void checkInterval()
Check timer interval in specific time unit is valid (static check)
Definition: CallbackTimer.h:289
void(* TimerCallback)(void *arg)
Interrupt-compatible C callback function pointer.
Definition: CallbackTimer.h:23
bool checkInterval(TickType ticks) const
Check timer interval is valid.
Definition: CallbackTimer.h:270
void setInterval()
Set timer interval in timer ticks (static check)
Definition: CallbackTimer.h:324
static constexpr uint64_t usToTicks()
Convert microsecond count into timer ticks.
Definition: CallbackTimer.h:98
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 void checkIntervalUs()
Check timer interval in microseconds is valid (static check)
Definition: CallbackTimer.h:301
The String class.
Definition: WString.h:136
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
Class template for accessing a Clock in specific time units.
Definition: NanoTime.h:122
bool restart()
Restart timer.
Definition: CallbackTimer.h:235
bool setInterval(TimeType time)
Set timer interval in timer ticks.
Definition: CallbackTimer.h:344
bool setIntervalUs(TimeType microseconds)
Set timer interval in microseconds.
Definition: CallbackTimer.h:350
Time< T > time(Unit unit, T value)
Helper function to create a Time and deduce the type.
Definition: NanoTime.h:429
Callback timer class template.
Definition: CallbackTimer.h:70
TickType getInterval() const
Get timer interval in clock ticks.
Definition: CallbackTimer.h:261
static constexpr uint64_t ticksToUs()
Convert timer ticks into microseconds.
Definition: CallbackTimer.h:110
void setCallback(InterruptCallback callback)
Set timer trigger callback.
Definition: CallbackTimer.h:390
CallbackTimer & initializeMs(TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds (static check) with Timer Callback and optional argument...
Definition: CallbackTimer.h:181
void setCallback(TimerCallback callback, void *arg=nullptr)
Set timer trigger callback.
Definition: CallbackTimer.h:377
void setIntervalMs()
Set timer interval in milliseconds (static check)
Definition: CallbackTimer.h:368
static constexpr const char * typeName()
Definition: CallbackTimer.h:31
String toString(enum MimeType m)
Get textual representation for a MIME type.
void stop()
Stops timer.
Definition: CallbackTimer.h:223
bool start(bool repeating=true)
Start timer running.
Definition: CallbackTimer.h:413
CallbackTimer & initializeUs(TimeType microseconds, InterruptCallback callback=nullptr)
Initialise timer in microseconds with optional Interrupt Callback (no arg)
Definition: CallbackTimer.h:174
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:255
void setInterval()
Set timer interval in specific time unit (static check)
Definition: CallbackTimer.h:335
static constexpr Micros micros()
Get a microsecond time source.
Definition: CallbackTimer.h:92
NanoTime::Time< TimeType > getIntervalUs() const
Get timer interval in microseconds.
Definition: CallbackTimer.h:249
Callback timer API class template.
Definition: CallbackTimer.h:30
CallbackTimer & initialize(TimerCallback callback, void *arg=nullptr)
Initialise timer with an interval (static check) and callback.
Definition: CallbackTimer.h:130
bool startOnce()
Start one-shot timer.
Definition: CallbackTimer.h:216
Class to handle a simple time value with associated unit.
Definition: NanoTime.h:123
String toString() const
Definition: CallbackTimer.h:45
static constexpr Millis millis()
Get a millisecond time source.
Definition: CallbackTimer.h:86
static constexpr void checkInterval()
Check timer interval in ticks is valid (static check)
Definition: CallbackTimer.h:279
static constexpr void checkIntervalMs()
Check timer interval in milliseconds is valid (static check)
Definition: CallbackTimer.h:295
CallbackTimer & initializeUs(TimeType microseconds, TimerCallback callback, void *arg=nullptr)
Initialise timer in microseconds with Timer Callback and optional argument.
Definition: CallbackTimer.h:167
CallbackTimer & initializeUs(InterruptCallback callback=nullptr)
Initialise timer in microseconds (static check) with optional Interrupt Callback (no argument) ...
Definition: CallbackTimer.h:161
bool isStarted() const
Check if timer is started.
Definition: CallbackTimer.h:243