Skip to content

Allow using argument with attachInterrupt #1535

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 8 commits into from
Jul 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 29 additions & 9 deletions cores/esp32/esp32-hal-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
};

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"

Expand Down Expand Up @@ -193,7 +198,7 @@ extern int IRAM_ATTR __digitalRead(uint8_t pin)

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_h=0;
Expand All @@ -207,8 +212,12 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
if(gpio_intr_status_l) {
do {
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
if(__pinInterruptHandlers[pin]) {
__pinInterruptHandlers[pin]();
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} while(++pin<32);
Expand All @@ -217,23 +226,28 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
pin=32;
do {
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
if(__pinInterruptHandlers[pin]) {
__pinInterruptHandlers[pin]();
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} 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;

if(!interrupt_initialized) {
interrupt_initialized = true;
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);
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
GPIO.pin[pin].int_ena = 1;
Expand All @@ -244,10 +258,15 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
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)
{
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_type = 0;
esp_intr_enable(gpio_intr_handle);
Expand All @@ -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 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 attachInterruptArg(uint8_t pin, voidFuncPtr handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

1 change: 1 addition & 0 deletions cores/esp32/esp32-hal-gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);

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);

#ifdef __cplusplus
Expand Down
45 changes: 45 additions & 0 deletions libraries/ESP32/examples/GPIOInterrupt/GPIOInterrupt.ino
Original file line number Diff line number Diff line change
@@ -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);
}
}