Allow using argument with attachInterrupt (#1535)

* Allow using argument with attachInterrupt

* formatting

replace tabs with spaces

* fix bug more then 1 interrupt

* leftover

* add example

* make attachInterruptArg public

* update example

* leftover
This commit is contained in:
Bert Melis 2018-07-07 11:26:58 +02:00 committed by Me No Dev
parent 901a341949
commit c77aed4ac4
3 changed files with 75 additions and 9 deletions

View File

@ -70,7 +70,12 @@ const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
}; };
typedef void (*voidFuncPtr)(void); typedef void (*voidFuncPtr)(void);
static voidFuncPtr __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,}; typedef void (*voidFuncPtrArg)(void*);
typedef struct {
voidFuncPtr fn;
void* arg;
} InterruptHandle_t;
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
#include "driver/rtc_io.h" #include "driver/rtc_io.h"
@ -193,7 +198,7 @@ extern int IRAM_ATTR __digitalRead(uint8_t pin)
static intr_handle_t gpio_intr_handle = NULL; static intr_handle_t gpio_intr_handle = NULL;
static void IRAM_ATTR __onPinInterrupt(void *arg) static void IRAM_ATTR __onPinInterrupt()
{ {
uint32_t gpio_intr_status_l=0; uint32_t gpio_intr_status_l=0;
uint32_t gpio_intr_status_h=0; uint32_t gpio_intr_status_h=0;
@ -207,8 +212,12 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
if(gpio_intr_status_l) { if(gpio_intr_status_l) {
do { do {
if(gpio_intr_status_l & ((uint32_t)1 << pin)) { if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
if(__pinInterruptHandlers[pin]) { if(__pinInterruptHandlers[pin].fn) {
__pinInterruptHandlers[pin](); if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
} }
} }
} while(++pin<32); } while(++pin<32);
@ -217,15 +226,19 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
pin=32; pin=32;
do { do {
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) { if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
if(__pinInterruptHandlers[pin]) { if(__pinInterruptHandlers[pin].fn) {
__pinInterruptHandlers[pin](); if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
} }
} }
} while(++pin<GPIO_PIN_COUNT); } while(++pin<GPIO_PIN_COUNT);
} }
} }
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
{ {
static bool interrupt_initialized = false; static bool interrupt_initialized = false;
@ -233,7 +246,8 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
interrupt_initialized = true; interrupt_initialized = true;
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle); esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle);
} }
__pinInterruptHandlers[pin] = userFunc; __pinInterruptHandlers[pin].fn = (voidFuncPtr)userFunc;
__pinInterruptHandlers[pin].arg = arg;
esp_intr_disable(gpio_intr_handle); esp_intr_disable(gpio_intr_handle);
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
GPIO.pin[pin].int_ena = 1; GPIO.pin[pin].int_ena = 1;
@ -244,10 +258,15 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
esp_intr_enable(gpio_intr_handle); esp_intr_enable(gpio_intr_handle);
} }
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) {
__attachInterruptArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type);
}
extern void __detachInterrupt(uint8_t pin) extern void __detachInterrupt(uint8_t pin)
{ {
esp_intr_disable(gpio_intr_handle); esp_intr_disable(gpio_intr_handle);
__pinInterruptHandlers[pin] = NULL; __pinInterruptHandlers[pin].fn = NULL;
__pinInterruptHandlers[pin].arg = NULL;
GPIO.pin[pin].int_ena = 0; GPIO.pin[pin].int_ena = 0;
GPIO.pin[pin].int_type = 0; GPIO.pin[pin].int_type = 0;
esp_intr_enable(gpio_intr_handle); esp_intr_enable(gpio_intr_handle);
@ -258,5 +277,6 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite"))); extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"))); 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 attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
extern void attachInterruptArg(uint8_t pin, voidFuncPtr handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

View File

@ -79,6 +79,7 @@ void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin); int digitalRead(uint8_t pin);
void attachInterrupt(uint8_t pin, void (*)(void), int mode); void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void attachInterruptArg(uint8_t pin, void (*)(void), void * arg, int mode);
void detachInterrupt(uint8_t pin); void detachInterrupt(uint8_t pin);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,45 @@
#include <Arduino.h>
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
Button button1 = {23, 0, false};
Button button2 = {18, 0, false};
void IRAM_ATTR isr(void* arg) {
Button* s = static_cast<Button*>(arg);
s->numberKeyPresses += 1;
s->pressed = true;
}
void IRAM_ATTR isr() {
button2.numberKeyPresses += 1;
button2.pressed = true;
}
void setup() {
Serial.begin(115200);
pinMode(button1.PIN, INPUT_PULLUP);
attachInterruptArg(button1.PIN, isr, &button1, FALLING);
pinMode(button2.PIN, INPUT_PULLUP);
attachInterrupt(button2.PIN, isr, FALLING);
}
void loop() {
if (button1.pressed) {
Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
button1.pressed = false;
}
if (button2.pressed) {
Serial.printf("Button 2 has been pressed %u times\n", button2.numberKeyPresses);
button2.pressed = false;
}
static uint32_t lastMillis = 0;
if (millis() - lastMillis > 10000) {
lastMillis = millis();
detachInterrupt(button1.PIN);
}
}