diff --git a/examples/buttonInterrupt.cpp b/examples/buttonInterrupt.cpp new file mode 100644 index 0000000..90bb7a4 --- /dev/null +++ b/examples/buttonInterrupt.cpp @@ -0,0 +1,22 @@ +#include "Arduino.h" +#include "Eventy.h" + +#define BUTTON_PIN 14 + +using namespace eventy; + +Eventy eventy_manager; + +EventCollection onInterrupt() { + Serial.println("button pressed!"); + return {}; +} + +void setup() { + Serial.begin(115200); + eventy_manager.registerHardwareInterrupt(BUTTON_PIN, onInterrupt, 500, INPUT_PULLUP, FALLING); +} + +void loop() { + vTaskDelete(NULL); +} diff --git a/include/Eventy.h b/include/Eventy.h index 7364d65..8c225a8 100644 --- a/include/Eventy.h +++ b/include/Eventy.h @@ -6,5 +6,4 @@ #include "eventy/QueueBroker.h" #include "eventy/Task.h" #include "eventy/FunctionTask.h" -#include "eventy/ButtonTask.h" - +#include "eventy/TimeoutTask.h" diff --git a/include/eventy/ButtonTask.h b/include/eventy/ButtonTask.h deleted file mode 100644 index 5e3d13d..0000000 --- a/include/eventy/ButtonTask.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef EVENTY_BUTTON_TASK_H -#define EVENTY_BUTTON_TASK_H - -#include "Arduino.h" -#include "Task.h" - -namespace eventy { - -class ButtonTask : public Task { -public: - ButtonTask(const char *topic, int pin); - void begin() override; - EventCollection run() override; - bool isReady() override; -private: - const char *_topic; - int _pin; - portMUX_TYPE _mux = portMUX_INITIALIZER_UNLOCKED; - bool _is_pressed = false; - static void IRAM_ATTR handleButtonInterrupt(void *instance_ptr); -}; - -} - -#endif // EVENTY_BUTTON_TASK_H diff --git a/include/eventy/Eventy.h b/include/eventy/Eventy.h index 7a5619e..bd4288d 100644 --- a/include/eventy/Eventy.h +++ b/include/eventy/Eventy.h @@ -7,6 +7,7 @@ #include "EventHandler.h" #include "Task.h" #include "FunctionTask.h" +#include "TimeoutTask.h" #define MAX_ALLOWED_FUNCTION_TASKS 20 #define MAIN_EVENTS_QUEUE_MAX_SIZE 300 @@ -27,6 +28,10 @@ class Eventy { TaskHandle_t registerTask(EventCollection(*function)(void), unsigned int timer_delay_in_ms, const char *name = DEFAULT_TASK_NAME, int stack_size = DEFAULT_TASK_STACK_SIZE, UBaseType_t priority = tskIDLE_PRIORITY, BaseType_t core = DEFAULT_TASK_CORE); + TaskHandle_t registerHardwareInterrupt(int pin, EventCollection(*function)(void), int debounce_ms = 100, + int pin_mode = INPUT_PULLUP, int interrupt_mode = FALLING, + const char *name = DEFAULT_TASK_NAME, int stack_size = DEFAULT_TASK_STACK_SIZE, + UBaseType_t priority = tskIDLE_PRIORITY, BaseType_t core = DEFAULT_TASK_CORE); BaseType_t registerEventHandler(Topic topic, EventHandler *message_handler); template EventHandler *registerEventHandler(Topic topic, EventCollection(*function)(Event)); @@ -39,8 +44,9 @@ class Eventy { BaseType_t getFreeSpot(int &index); BaseType_t getTaskHandleIndex(TaskHandle_t task_handle, int &index); + TaskHandle_t initializeFunctionTask(TaskHandle_t task_handle, Task *task); - TaskData _task_table[MAX_ALLOWED_FUNCTION_TASKS]; + TaskData _function_task_table[MAX_ALLOWED_FUNCTION_TASKS]; QueueHandle_t _event_queue = nullptr; QueueTXHandler *_event_tx_handler = nullptr; QueueRXHandler *_event_rx_handler = nullptr; diff --git a/include/eventy/Task.h b/include/eventy/Task.h index 9630364..9544cde 100644 --- a/include/eventy/Task.h +++ b/include/eventy/Task.h @@ -22,6 +22,7 @@ class TaskRunner { ~TaskRunner(); TaskHandle_t begin(Task *task, unsigned int _timer_delay_in_ms, const char *name, int stack_size, UBaseType_t priority, BaseType_t core); + void stop(TaskHandle_t task_handle); private: class TaskData { public: diff --git a/include/eventy/TimeoutTask.h b/include/eventy/TimeoutTask.h new file mode 100644 index 0000000..01cb3c3 --- /dev/null +++ b/include/eventy/TimeoutTask.h @@ -0,0 +1,21 @@ +#ifndef EVENTY_TIMEOUT_TASK_H +#define EVENTY_TIMEOUT_TASK_H + +#include "Arduino.h" +#include "Task.h" + +namespace eventy { + +class TimeoutTask : public Task { +public: + TimeoutTask(EventCollection(*function)(void), int timeout); + EventCollection run() override; + bool isReady() override; +private: + EventCollection (*_function)(void); + int _timeout; +}; + +} + +#endif // EVENTY_TIMEOUT_TASK_H diff --git a/src/Eventy.cpp b/src/Eventy.cpp index 6a9c3a5..cbfa903 100644 --- a/src/Eventy.cpp +++ b/src/Eventy.cpp @@ -22,8 +22,8 @@ Eventy::Eventy(unsigned int poll_delay_in_ms, int stack_size, BaseType_t core) { Eventy::~Eventy() { for (int i = 0; i < MAX_ALLOWED_FUNCTION_TASKS; i++) { - if (_task_table[i].task_handle != nullptr) { - delete _task_table[i].task; + if (_function_task_table[i].task_handle != nullptr) { + delete _function_task_table[i].task; } } delete _event_manager; @@ -35,7 +35,7 @@ Eventy::~Eventy() { BaseType_t Eventy::getTaskHandleIndex(TaskHandle_t task_handle, int &index) { for (int i = 0; i < MAX_ALLOWED_FUNCTION_TASKS; i++) { - if (_task_table[i].task_handle == task_handle) { + if (_function_task_table[i].task_handle == task_handle) { index = i; return pdTRUE; } @@ -47,6 +47,21 @@ BaseType_t Eventy::getFreeSpot(int &index) { return getTaskHandleIndex(nullptr, index); } +TaskHandle_t Eventy::initializeFunctionTask(TaskHandle_t task_handle, Task *task) { + int index; + if ((getFreeSpot(index) == pdFALSE) || (task_handle == nullptr)) { + if (task_handle != nullptr) { + _task_runner->stop(task_handle); + } + delete task; + return nullptr; + } + + _function_task_table[index].task = task; + _function_task_table[index].task_handle = task_handle; + return task_handle; +} + TaskHandle_t Eventy::registerTask( Task *task, unsigned int timer_delay_in_ms, @@ -54,11 +69,7 @@ TaskHandle_t Eventy::registerTask( int stack_size, UBaseType_t priority, BaseType_t core) { - int free_index; - if (getFreeSpot(free_index) == pdFALSE) { - return nullptr; - } - + return _task_runner->begin(task, timer_delay_in_ms, name, stack_size, priority, core); } @@ -70,16 +81,26 @@ TaskHandle_t Eventy::registerTask( UBaseType_t priority, BaseType_t core) { Task *task = new FunctionTask(function); - TaskHandle_t task_handle = registerTask(task, timer_delay_in_ms, name, stack_size, priority, core); - int index; - if ((task_handle != nullptr) && (getFreeSpot(index) != pdFALSE)) { - _task_table[index].task = task; - _task_table[index].task_handle = task_handle; - return task_handle; - } + return initializeFunctionTask(registerTask(task, timer_delay_in_ms, name, stack_size, priority, core), task); +} - delete task; - return nullptr; +TaskHandle_t Eventy::registerHardwareInterrupt( + int pin, + EventCollection(*function)(void), + int debounce_ms, + int pin_mode, + int interrupt_mode, + const char *name, + int stack_size, + UBaseType_t priority, + BaseType_t core) { + Task *task = new TimeoutTask(function, debounce_ms); + TaskHandle_t task_handle = initializeFunctionTask(registerTask(task, 5, name, stack_size, priority, core), task); + if (task_handle != nullptr) { + pinMode(pin, pin_mode); + attachInterruptArg(digitalPinToInterrupt(pin), [](TaskHandle_t handle){xTaskResumeFromISR(handle);}, task_handle, interrupt_mode); + } + return task_handle; } } diff --git a/src/Task.cpp b/src/Task.cpp index 54cb6c7..5f0efe0 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -73,6 +73,13 @@ TaskRunner::begin( return _task_data_table[index].task_handle; } +void TaskRunner::stop(xTaskHandle task_handle) { + int index; + getTaskHandleIndex(task_handle, index); + _task_data_table[index].unset(); + vTaskDelete(task_handle); +} + void TaskRunner::run(void *parameter) { TaskData *running_task_data = static_cast(parameter); Task *task = running_task_data->task; diff --git a/src/TimeoutTask.cpp b/src/TimeoutTask.cpp new file mode 100644 index 0000000..3907419 --- /dev/null +++ b/src/TimeoutTask.cpp @@ -0,0 +1,18 @@ +#include "eventy/TimeoutTask.h" + +namespace eventy { + +TimeoutTask::TimeoutTask(EventCollection(*function)(void), int timeout) : _function(function), _timeout(timeout) { +} + +EventCollection TimeoutTask::run() { + vTaskSuspend(NULL); + delay(_timeout); + return _function(); +} + +bool TimeoutTask::isReady() { + return true; +} + +}