diff --git a/cores/esp8266/FunctionalInterrupt.cpp b/cores/esp8266/FunctionalInterrupt.cpp new file mode 100644 index 000000000..b7c7dd143 --- /dev/null +++ b/cores/esp8266/FunctionalInterrupt.cpp @@ -0,0 +1,24 @@ +#include + + +// Duplicate typedefs from core_esp8266_wiring_digital_c +typedef void (*voidFuncPtr)(void); + +// Helper functions for Functional interrupt routines +extern "C" void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void*fp , int mode); + +// Structure for communication +struct ArgStructure { + std::function reqFunction; +}; + +void interruptFunctional(void* arg) +{ + ((ArgStructure*)arg)->reqFunction(); +} + +void attachInterrupt(uint8_t pin, std::function intRoutine, int mode) +{ + // use the local interrupt routine which takes the ArgStructure as argument + __attachInterruptArg (pin, (voidFuncPtr)interruptFunctional, new ArgStructure{intRoutine}, mode); +} diff --git a/cores/esp8266/FunctionalInterrupt.h b/cores/esp8266/FunctionalInterrupt.h new file mode 100644 index 000000000..fedc20ad6 --- /dev/null +++ b/cores/esp8266/FunctionalInterrupt.h @@ -0,0 +1,15 @@ +#ifndef FUNCTIONALINTERRUPT_H +#define FUNCTIONALINTERRUPT_H + +#include +#include +#include + +extern "C" { +#include "c_types.h" +#include "ets_sys.h" +} + +void attachInterrupt(uint8_t pin, std::function intRoutine, int mode); + +#endif //INTERRUPTS_H diff --git a/cores/esp8266/core_esp8266_wiring_digital.c b/cores/esp8266/core_esp8266_wiring_digital.c index 3e304b864..5df128833 100644 --- a/cores/esp8266/core_esp8266_wiring_digital.c +++ b/cores/esp8266/core_esp8266_wiring_digital.c @@ -105,12 +105,15 @@ extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { */ typedef void (*voidFuncPtr)(void); +typedef void (*voidFuncPtrArg)(void*); typedef struct { uint8_t mode; void (*fn)(void); + void * arg; } interrupt_handler_t; + static interrupt_handler_t interrupt_handlers[16]; static uint32_t interrupt_reg = 0; @@ -127,24 +130,32 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) { while(!(changedbits & (1 << i))) i++; changedbits &= ~(1 << i); interrupt_handler_t *handler = &interrupt_handlers[i]; - if (handler->fn && - (handler->mode == CHANGE || + if (handler->fn && + (handler->mode == CHANGE || (handler->mode & 1) == !!(levels & (1 << i)))) { // to make ISR compatible to Arduino AVR model where interrupts are disabled // we disable them before we call the client ISR - uint32_t savedPS = xt_rsil(15); // stop other interrupts - handler->fn(); - xt_wsr_ps(savedPS); + uint32_t savedPS = xt_rsil(15); // stop other interrupts + if (handler->arg) + { + ((voidFuncPtrArg)handler->fn)(handler->arg); + } + else + { + handler->fn(); + } + xt_wsr_ps(savedPS); } } ETS_GPIO_INTR_ENABLE(); } -extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode) { +extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void *arg, int mode) { if(pin < 16) { interrupt_handler_t *handler = &interrupt_handlers[pin]; handler->mode = mode; handler->fn = userFunc; + handler->arg = arg; interrupt_reg |= (1 << pin); GPC(pin) &= ~(0xF << GPCI);//INT mode disabled GPIEC = (1 << pin); //Clear Interrupt for this pin @@ -152,6 +163,11 @@ extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, } } +extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode ) +{ + __attachInterruptArg (pin, userFunc, 0, mode); +} + extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) { if(pin < 16) { GPC(pin) &= ~(0xF << GPCI);//INT mode disabled @@ -160,6 +176,7 @@ extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) { interrupt_handler_t *handler = &interrupt_handlers[pin]; handler->mode = 0; handler->fn = 0; + handler->arg = 0; } } @@ -176,7 +193,7 @@ void initPins() { for (int i = 12; i <= 16; ++i) { pinMode(i, INPUT); } - + ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg); ETS_GPIO_INTR_ENABLE(); } @@ -186,3 +203,4 @@ extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias(" extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"))); extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); +