diff --git a/libraries/Ticker/Ticker.cpp b/libraries/Ticker/Ticker.cpp index a5e750a60..b348798c6 100644 --- a/libraries/Ticker/Ticker.cpp +++ b/libraries/Ticker/Ticker.cpp @@ -29,6 +29,9 @@ extern "C" { #include "osapi.h" } +const int ONCE = 0; +const int REPEAT = 1; + #include "Ticker.h" Ticker::Ticker() @@ -41,10 +44,8 @@ Ticker::~Ticker() detach(); } -void Ticker::_attach_ms(callback_with_arg_t callback, uint32_t milliseconds, void* arg) +void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg) { - const int REPEAT = 1; - if (_timer) { os_timer_disarm(_timer); @@ -54,8 +55,8 @@ void Ticker::_attach_ms(callback_with_arg_t callback, uint32_t milliseconds, voi _timer = new ETSTimer; } - os_timer_setfn(_timer, reinterpret_cast(callback), arg); - os_timer_arm(_timer, milliseconds, REPEAT); + os_timer_setfn(_timer, reinterpret_cast(callback), reinterpret_cast(arg)); + os_timer_arm(_timer, milliseconds, (repeat)?REPEAT:ONCE); } void Ticker::detach() diff --git a/libraries/Ticker/Ticker.h b/libraries/Ticker/Ticker.h index c107532ed..ea3f59f1c 100644 --- a/libraries/Ticker/Ticker.h +++ b/libraries/Ticker/Ticker.h @@ -37,36 +37,65 @@ public: typedef void (*callback_t)(void); typedef void (*callback_with_arg_t)(void*); - void attach(callback_t callback, float seconds) + void attach(float seconds, callback_t callback) { - _attach_ms(reinterpret_cast(callback), seconds * 1000, 0); + _attach_ms(seconds * 1000, true, reinterpret_cast(callback), 0); } - void attach_ms(callback_t callback, uint32_t milliseconds) + void attach_ms(uint32_t milliseconds, callback_t callback) { - _attach_ms(reinterpret_cast(callback), milliseconds, 0); + _attach_ms(milliseconds, true, reinterpret_cast(callback), 0); } template - void attach(void (*callback)(TArg), float seconds, TArg arg) + void attach(float seconds, void (*callback)(TArg), TArg arg) { static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes"); - uint32_t arg32 = static_cast(arg); - _attach_ms(reinterpret_cast(callback), seconds * 1000, reinterpret_cast(arg32)); + // C-cast serves two purposes: + // static_cast for smaller integer types, + // reinterpret_cast + const_cast for pointer types + uint32_t arg32 = (uint32_t)arg; + _attach_ms(seconds * 1000, true, reinterpret_cast(callback), arg32); } template - void attach_ms(void (*callback)(TArg), uint32_t milliseconds, TArg arg) + void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) { static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes"); - uint32_t arg32 = static_cast(arg); - _attach_ms(reinterpret_cast(callback), milliseconds, reinterpret_cast(arg32)); + uint32_t arg32 = (uint32_t)arg; + _attach_ms(milliseconds, true, reinterpret_cast(callback), arg32); + } + + void once(float seconds, callback_t callback) + { + _attach_ms(seconds * 1000, false, reinterpret_cast(callback), 0); + } + + void once_ms(uint32_t milliseconds, callback_t callback) + { + _attach_ms(milliseconds, false, reinterpret_cast(callback), 0); + } + + template + void once(float seconds, void (*callback)(TArg), TArg arg) + { + static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes"); + uint32_t arg32 = (uint32_t)(arg); + _attach_ms(seconds * 1000, false, reinterpret_cast(callback), arg32); + } + + template + void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) + { + static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes"); + uint32_t arg32 = (uint32_t)(arg); + _attach_ms(milliseconds, false, reinterpret_cast(callback), arg32); } void detach(); protected: - void _attach_ms(callback_with_arg_t callback, uint32_t milliseconds, void* arg); + void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg); protected: diff --git a/libraries/Ticker/examples/TickerBasic/TickerBasic.ino b/libraries/Ticker/examples/TickerBasic/TickerBasic.ino index 4b21818e5..772b5b74c 100644 --- a/libraries/Ticker/examples/TickerBasic/TickerBasic.ino +++ b/libraries/Ticker/examples/TickerBasic/TickerBasic.ino @@ -28,7 +28,7 @@ void flip() // when the counter reaches a certain value, start blinking like crazy if (count == 20) { - flipper.attach(&flip, 0.1); + flipper.attach(0.1, flip); } // when the counter reaches yet another value, stop blinking else if (count == 120) @@ -42,7 +42,7 @@ void setup() { digitalWrite(1, LOW); // flip the pin every 0.3s - flipper.attach(&flip, 0.3); + flipper.attach(0.3, flip); } void loop() { diff --git a/libraries/Ticker/examples/TickerParameter/TickerParameter.ino b/libraries/Ticker/examples/TickerParameter/TickerParameter.ino index 832f35405..80eec5e67 100644 --- a/libraries/Ticker/examples/TickerParameter/TickerParameter.ino +++ b/libraries/Ticker/examples/TickerParameter/TickerParameter.ino @@ -25,11 +25,11 @@ void setup() { pinMode(1, OUTPUT); digitalWrite(1, LOW); - // call setPin(0) every 25 ms - tickerSetLow.attach_ms(&setPin, 25, 0); + // every 25 ms, call setPin(0) + tickerSetLow.attach_ms(25, setPin, 0); - // call setPin(1) every 26 ms - tickerSetHigh.attach_ms(&setPin, 26, 1); + // every 26 ms, call setPin(1) + tickerSetHigh.attach_ms(26, setPin, 1); } void loop() { diff --git a/libraries/Ticker/keywords.txt b/libraries/Ticker/keywords.txt index 8fae1c33e..89cca9a0c 100644 --- a/libraries/Ticker/keywords.txt +++ b/libraries/Ticker/keywords.txt @@ -12,6 +12,8 @@ attach KEYWORD2 attach_ms KEYWORD2 +once KEYWORD2 +once_ms KEYWORD2 detach KEYWORD2 #######################################