From 05c5e468de5f2f2254a366a07befc3f851b39c0a Mon Sep 17 00:00:00 2001 From: hreintke Date: Thu, 19 Jul 2018 13:38:52 +0200 Subject: [PATCH 1/5] Initial --- cores/esp32/FunctionalInterrupt.cpp | 44 +++++++++++++++++++++++++++++ cores/esp32/FunctionalInterrupt.h | 20 +++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 cores/esp32/FunctionalInterrupt.cpp create mode 100644 cores/esp32/FunctionalInterrupt.h diff --git a/cores/esp32/FunctionalInterrupt.cpp b/cores/esp32/FunctionalInterrupt.cpp new file mode 100644 index 00000000000..43427a3f64f --- /dev/null +++ b/cores/esp32/FunctionalInterrupt.cpp @@ -0,0 +1,44 @@ +/* + * FunctionalInterrupt.cpp + * + * Created on: 8 jul. 2018 + * Author: Herman + */ + +#include "FunctionalInterrupt.h" +#include "Arduino.h" + +typedef void (*voidFuncPtr)(void); +typedef void (*voidFuncPtrArg)(void*); + +extern "C" +{ + extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type); +} + +void interruptFunctional(void* arg) +{ + InterruptArgStructure* localArg = (InterruptArgStructure*)arg; + if (localArg->interruptFunction) + { + localArg->interruptFunction(); + } +} + +void attachInterrupt(uint8_t pin, std::function intRoutine, int mode) +{ + // use the local interrupt routine which takes the ArgStructure as argument + __attachInterruptArg (pin, (voidFuncPtrArg)interruptFunctional, new InterruptArgStructure{intRoutine}, mode); +} + +extern "C" +{ + void cleanupFunctional(void* arg) + { + delete (InterruptArgStructure*)arg; + } +} + + + + diff --git a/cores/esp32/FunctionalInterrupt.h b/cores/esp32/FunctionalInterrupt.h new file mode 100644 index 00000000000..b5e3181f986 --- /dev/null +++ b/cores/esp32/FunctionalInterrupt.h @@ -0,0 +1,20 @@ +/* + * FunctionalInterrupt.h + * + * Created on: 8 jul. 2018 + * Author: Herman + */ + +#ifndef CORE_CORE_FUNCTIONALINTERRUPT_H_ +#define CORE_CORE_FUNCTIONALINTERRUPT_H_ + +#include + +struct InterruptArgStructure { + std::function interruptFunction; +}; + +void attachInterrupt(uint8_t pin, std::function intRoutine, int mode); + + +#endif /* CORE_CORE_FUNCTIONALINTERRUPT_H_ */ From b21b3b9d50b245367772081f7a995734cd85daa6 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 5 Aug 2018 12:33:59 +0200 Subject: [PATCH 2/5] Implementation --- cores/esp32/FunctionalInterrupt.cpp | 4 ++-- cores/esp32/esp32-hal-gpio.c | 28 +++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/cores/esp32/FunctionalInterrupt.cpp b/cores/esp32/FunctionalInterrupt.cpp index 43427a3f64f..dd06f5dedb2 100644 --- a/cores/esp32/FunctionalInterrupt.cpp +++ b/cores/esp32/FunctionalInterrupt.cpp @@ -13,7 +13,7 @@ typedef void (*voidFuncPtrArg)(void*); extern "C" { - extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type); + extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional); } void interruptFunctional(void* arg) @@ -28,7 +28,7 @@ void interruptFunctional(void* arg) void attachInterrupt(uint8_t pin, std::function intRoutine, int mode) { // use the local interrupt routine which takes the ArgStructure as argument - __attachInterruptArg (pin, (voidFuncPtrArg)interruptFunctional, new InterruptArgStructure{intRoutine}, mode); + __attachInterruptFunctionalArg (pin, (voidFuncPtrArg)interruptFunctional, new InterruptArgStructure{intRoutine}, mode, true); } extern "C" diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 795dba2b7ab..9b2b51577ac 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -74,6 +74,7 @@ typedef void (*voidFuncPtrArg)(void*); typedef struct { voidFuncPtr fn; void* arg; + bool functional; } InterruptHandle_t; static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,}; @@ -238,16 +239,26 @@ static void IRAM_ATTR __onPinInterrupt() } } -extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type) +extern void cleanupFunctional(void* arg); + +extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional) { static bool interrupt_initialized = false; - + if(!interrupt_initialized) { interrupt_initialized = true; esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle); } + + // if new attach without detach remove old info + if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg) + { + cleanupFunctional(__pinInterruptHandlers[pin].arg); + } __pinInterruptHandlers[pin].fn = (voidFuncPtr)userFunc; __pinInterruptHandlers[pin].arg = arg; + __pinInterruptHandlers[pin].functional = functional; + esp_intr_disable(gpio_intr_handle); if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU GPIO.pin[pin].int_ena = 1; @@ -258,15 +269,26 @@ extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * ar esp_intr_enable(gpio_intr_handle); } +extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type) +{ + __attachInterruptFunctionalArg(pin, userFunc, arg, intr_type, false); +} + extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) { - __attachInterruptArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type); + __attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type, false); } extern void __detachInterrupt(uint8_t pin) { esp_intr_disable(gpio_intr_handle); + if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg) + { + cleanupFunctional(__pinInterruptHandlers[pin].arg); + } __pinInterruptHandlers[pin].fn = NULL; __pinInterruptHandlers[pin].arg = NULL; + __pinInterruptHandlers[pin].arg = false; + GPIO.pin[pin].int_ena = 0; GPIO.pin[pin].int_type = 0; esp_intr_enable(gpio_intr_handle); From 040b18806f66d447f8723a791dbcf7947c09cf18 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 5 Aug 2018 13:24:51 +0200 Subject: [PATCH 3/5] Add to CMakelist.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e0d89a796b..9d2544c7bbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(CORE_SRCS cores/esp32/esp32-hal-touch.c cores/esp32/esp32-hal-uart.c cores/esp32/Esp.cpp + cores/esp32/FunctionalInterrupt.cpp cores/esp32/HardwareSerial.cpp cores/esp32/IPAddress.cpp cores/esp32/IPv6Address.cpp From db67da00bfacb325956d70974ac1d100c04eb5ef Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 20 Aug 2018 16:11:04 +0200 Subject: [PATCH 4/5] Add example --- .../FunctionalInterrupt.ino | 47 +++++++++++++++++++ .../GPIOInterrupt/GPIOInterrupt.ino | 0 2 files changed, 47 insertions(+) create mode 100644 libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino rename libraries/ESP32/examples/{ => GPIO}/GPIOInterrupt/GPIOInterrupt.ino (100%) diff --git a/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino new file mode 100644 index 00000000000..0e9f97414bb --- /dev/null +++ b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino @@ -0,0 +1,47 @@ +#include +#include + +#define BUTTON1 16 +#define BUTTON2 17 + +class Button +{ +public: + Button(uint8_t reqPin) : PIN(reqPin){ + pinMode(PIN, INPUT_PULLUP); + attachInterrupt(PIN, std::bind(&Button::isr,this), FALLING); + }; + ~Button() { + detachInterrupt(PIN); + } + + void IRAM_ATTR isr() { + numberKeyPresses += 1; + pressed = true; + } + + void checkPressed() { + if (pressed) { + Serial.printf("Button on pin %u has been pressed %u times\n", PIN, numberKeyPresses); + pressed = false; + } + } + +private: + const uint8_t PIN; + volatile uint32_t numberKeyPresses; + volatile bool pressed; +}; + +Button button1(BUTTON1); +Button button2(BUTTON2); + + +void setup() { + Serial.begin(115200); +} + +void loop() { + button1.checkPressed(); + button2.checkPressed(); +} diff --git a/libraries/ESP32/examples/GPIOInterrupt/GPIOInterrupt.ino b/libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino similarity index 100% rename from libraries/ESP32/examples/GPIOInterrupt/GPIOInterrupt.ino rename to libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino From 2d5af6232c91efadabe9a02038bcd18469c041c6 Mon Sep 17 00:00:00 2001 From: hreintke Date: Mon, 20 Aug 2018 16:13:49 +0200 Subject: [PATCH 5/5] Add IRAM_ATTR --- cores/esp32/FunctionalInterrupt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/FunctionalInterrupt.cpp b/cores/esp32/FunctionalInterrupt.cpp index dd06f5dedb2..d2e6dfd4236 100644 --- a/cores/esp32/FunctionalInterrupt.cpp +++ b/cores/esp32/FunctionalInterrupt.cpp @@ -16,7 +16,7 @@ extern "C" extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional); } -void interruptFunctional(void* arg) +void IRAM_ATTR interruptFunctional(void* arg) { InterruptArgStructure* localArg = (InterruptArgStructure*)arg; if (localArg->interruptFunction)