Skip to content

Ticker updated to match extensions in ESP8266 API #2849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 0 additions & 51 deletions libraries/Ticker/examples/Arguments/Arguments.ino

This file was deleted.

49 changes: 49 additions & 0 deletions libraries/Ticker/examples/TickerBasic/TickerBasic.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Basic Ticker usage

Ticker is an object that will call a given function with a certain period.
Each Ticker calls one function. You can have as many Tickers as you like,
memory being the only limitation.

A function may be attached to a ticker and detached from the ticker.
There are two variants of the attach function: attach and attach_ms.
The first one takes period in seconds, the second one in milliseconds.

The built-in LED will be blinking.
*/

#include <Ticker.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

Ticker flipper;

int count = 0;

void flip() {
int state = digitalRead(LED_BUILTIN); // get the current state of GPIO1 pin
digitalWrite(LED_BUILTIN, !state); // set pin to the opposite state

++count;
// when the counter reaches a certain value, start blinking like crazy
if (count == 20) {
flipper.attach(0.1, flip);
}
// when the counter reaches yet another value, stop blinking
else if (count == 120) {
flipper.detach();
}
}

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);

// flip the pin every 0.3s
flipper.attach(0.3, flip);
}

void loop() {
}
54 changes: 54 additions & 0 deletions libraries/Ticker/examples/TickerParameter/TickerParameter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Passing paramters to Ticker callbacks
Apart from void(void) functions, the Ticker library supports
functions taking one argument. This argument's size has to be less or
equal to 4 bytes (so char, short, int, float, void*, char* types will do).
This sample runs two tickers that both call one callback function,
but with different arguments.
The built-in LED will be pulsing.
*/

#include <Ticker.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

Ticker tickerSetLow;
Ticker tickerSetHigh;
Ticker tickerSetChar;

void setPinLow() {
digitalWrite(LED_BUILTIN, 0);
}

void setPinHigh() {
digitalWrite(LED_BUILTIN, 1);
}

void setPin(int state) {
digitalWrite(LED_BUILTIN, state);
}

void setPinChar(char state) {
digitalWrite(LED_BUILTIN, state);
}

void setup() {
pinMode(LED_BUILTIN, OUTPUT);

// every 25 ms, call setPinLow()
tickerSetLow.attach_ms(25, setPinLow);

// every 26 ms, call setPinHigh()
tickerSetHigh.attach_ms(26, setPinHigh);

// every 54 ms, call setPinChar(1)
tickerSetChar.attach_ms(26, setPinChar, (char)1);
}

void loop() {
}
4 changes: 4 additions & 0 deletions libraries/Ticker/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ Ticker KEYWORD1

attach KEYWORD2
attach_ms KEYWORD2
attach_us KEYWORD2
once KEYWORD2
once_ms KEYWORD2
once_us KEYWORD2
detach KEYWORD2
active KEYWORD2
17 changes: 13 additions & 4 deletions libraries/Ticker/src/Ticker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Ticker::~Ticker() {
detach();
}

void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg) {
void Ticker::_attach_us(uint64_t micros, bool repeat, callback_with_arg_t callback, void* arg) {
esp_timer_create_args_t _timerConfig;
_timerConfig.arg = reinterpret_cast<void*>(arg);
_timerConfig.callback = callback;
Expand All @@ -43,9 +43,9 @@ void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t
}
esp_timer_create(&_timerConfig, &_timer);
if (repeat) {
esp_timer_start_periodic(_timer, milliseconds * 1000ULL);
esp_timer_start_periodic(_timer, micros);
} else {
esp_timer_start_once(_timer, milliseconds * 1000ULL);
esp_timer_start_once(_timer, micros);
}
}

Expand All @@ -54,10 +54,19 @@ void Ticker::detach() {
esp_timer_stop(_timer);
esp_timer_delete(_timer);
_timer = nullptr;
_callback_function = nullptr;
}
}

bool Ticker::active() {
bool Ticker::active() const {
if (!_timer) return false;
return esp_timer_is_active(_timer);
}

void Ticker::_static_callback(void* arg)
{
Ticker* _this = reinterpret_cast<Ticker*>(arg);
if (_this && _this->_callback_function)
_this->_callback_function();
}

83 changes: 57 additions & 26 deletions libraries/Ticker/src/Ticker.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,79 +28,110 @@
extern "C" {
#include "esp_timer.h"
}
#include <functional>

class Ticker
{
public:
Ticker();
~Ticker();
typedef void (*callback_t)(void);

typedef void (*callback_with_arg_t)(void*);
typedef std::function<void(void)> callback_function_t;

void attach(float seconds, callback_function_t callback)
{
_callback_function = std::move(callback);
_attach_us(1000000ULL * seconds, true, _static_callback, this);
}

void attach(float seconds, callback_t callback)
void attach_ms(uint64_t milliseconds, callback_function_t callback)
{
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
_callback_function = std::move(callback);
_attach_us(1000ULL * milliseconds, true, _static_callback, this);
}

void attach_ms(uint32_t milliseconds, callback_t callback)
void attach_us(uint64_t micros, callback_function_t callback)
{
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
_callback_function = std::move(callback);
_attach_us(micros, true, _static_callback, this);
}

template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes");
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
// 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_with_arg_t>(callback), arg32);
_attach_us(1000000ULL * seconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

template<typename TArg>
void attach_ms(uint64_t milliseconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
_attach_us(1000ULL * milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

template<typename TArg>
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
void attach_us(uint64_t micros, 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, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
_attach_us(micros, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

void once(float seconds, callback_t callback)
void once(float seconds, callback_function_t callback)
{
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
_callback_function = std::move(callback);
_attach_us(1000000ULL * seconds, false, _static_callback, this);
}

void once_ms(uint32_t milliseconds, callback_t callback)
void once_ms(uint64_t milliseconds, callback_function_t callback)
{
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
_callback_function = std::move(callback);
_attach_us(1000ULL * milliseconds, false, _static_callback, this);
}

void once_us(uint64_t micros, callback_function_t callback)
{
_callback_function = std::move(callback);
_attach_us(micros, false, _static_callback, this);
}

template<typename TArg>
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_with_arg_t>(callback), arg32);
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
_attach_us(1000000ULL * seconds, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

template<typename TArg>
void once_ms(uint64_t milliseconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
_attach_us(1000ULL * milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

template<typename TArg>
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
void once_us(uint64_t micros, 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_with_arg_t>(callback), arg32);
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
_attach_us(micros, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
}

void detach();
bool active();
bool active() const;

protected:
void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg);
static void _static_callback(void* arg);

callback_function_t _callback_function = nullptr;

protected:
esp_timer_handle_t _timer;

private:
void _attach_us(uint64_t micros, bool repeat, callback_with_arg_t callback, void* arg);
};


Expand Down