Skip to content

Commit ea61563

Browse files
hreintkeme-no-dev
authored andcommitted
Functional interrupt (espressif#1728)
* Initial * Implementation * Add to CMakelist.txt * Add example * Add IRAM_ATTR
1 parent 5be3078 commit ea61563

File tree

6 files changed

+137
-3
lines changed

6 files changed

+137
-3
lines changed

‎CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ set(CORE_SRCS
1717
cores/esp32/esp32-hal-touch.c
1818
cores/esp32/esp32-hal-uart.c
1919
cores/esp32/Esp.cpp
20+
cores/esp32/FunctionalInterrupt.cpp
2021
cores/esp32/HardwareSerial.cpp
2122
cores/esp32/IPAddress.cpp
2223
cores/esp32/IPv6Address.cpp
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* FunctionalInterrupt.cpp
3+
*
4+
* Created on: 8 jul. 2018
5+
* Author: Herman
6+
*/
7+
8+
#include"FunctionalInterrupt.h"
9+
#include"Arduino.h"
10+
11+
typedefvoid (*voidFuncPtr)(void);
12+
typedefvoid (*voidFuncPtrArg)(void*);
13+
14+
extern"C"
15+
{
16+
externvoid__attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional);
17+
}
18+
19+
void IRAM_ATTR interruptFunctional(void* arg)
20+
{
21+
InterruptArgStructure* localArg = (InterruptArgStructure*)arg;
22+
if (localArg->interruptFunction)
23+
{
24+
localArg->interruptFunction();
25+
}
26+
}
27+
28+
voidattachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
29+
{
30+
// use the local interrupt routine which takes the ArgStructure as argument
31+
__attachInterruptFunctionalArg (pin, (voidFuncPtrArg)interruptFunctional, new InterruptArgStructure{intRoutine}, mode, true);
32+
}
33+
34+
extern"C"
35+
{
36+
voidcleanupFunctional(void* arg)
37+
{
38+
delete (InterruptArgStructure*)arg;
39+
}
40+
}
41+
42+
43+
44+

‎cores/esp32/FunctionalInterrupt.h‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* FunctionalInterrupt.h
3+
*
4+
* Created on: 8 jul. 2018
5+
* Author: Herman
6+
*/
7+
8+
#ifndef CORE_CORE_FUNCTIONALINTERRUPT_H_
9+
#defineCORE_CORE_FUNCTIONALINTERRUPT_H_
10+
11+
#include<functional>
12+
13+
structInterruptArgStructure{
14+
std::function<void(void)> interruptFunction;
15+
};
16+
17+
voidattachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
18+
19+
20+
#endif/* CORE_CORE_FUNCTIONALINTERRUPT_H_ */

‎cores/esp32/esp32-hal-gpio.c‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ typedef void (*voidFuncPtrArg)(void*);
7474
typedefstruct{
7575
voidFuncPtrfn;
7676
void*arg;
77+
boolfunctional;
7778
} InterruptHandle_t;
7879
staticInterruptHandle_t__pinInterruptHandlers[GPIO_PIN_COUNT] ={0,};
7980

@@ -238,16 +239,26 @@ static void IRAM_ATTR __onPinInterrupt()
238239
}
239240
}
240241

241-
externvoid__attachInterruptArg(uint8_tpin, voidFuncPtrArguserFunc, void*arg, intintr_type)
242+
externvoidcleanupFunctional(void*arg);
243+
244+
externvoid__attachInterruptFunctionalArg(uint8_tpin, voidFuncPtrArguserFunc, void*arg, intintr_type, boolfunctional)
242245
{
243246
staticboolinterrupt_initialized= false;
244-
247+
245248
if(!interrupt_initialized){
246249
interrupt_initialized= true;
247250
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle);
248251
}
252+
253+
// if new attach without detach remove old info
254+
if (__pinInterruptHandlers[pin].functional&&__pinInterruptHandlers[pin].arg)
255+
{
256+
cleanupFunctional(__pinInterruptHandlers[pin].arg);
257+
}
249258
__pinInterruptHandlers[pin].fn= (voidFuncPtr)userFunc;
250259
__pinInterruptHandlers[pin].arg=arg;
260+
__pinInterruptHandlers[pin].functional=functional;
261+
251262
esp_intr_disable(gpio_intr_handle);
252263
if(esp_intr_get_cpu(gpio_intr_handle)){//APP_CPU
253264
GPIO.pin[pin].int_ena=1;
@@ -258,15 +269,26 @@ extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * ar
258269
esp_intr_enable(gpio_intr_handle);
259270
}
260271

272+
externvoid__attachInterruptArg(uint8_tpin, voidFuncPtrArguserFunc, void*arg, intintr_type)
273+
{
274+
__attachInterruptFunctionalArg(pin, userFunc, arg, intr_type, false);
275+
}
276+
261277
externvoid__attachInterrupt(uint8_tpin, voidFuncPtruserFunc, intintr_type){
262-
__attachInterruptArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type);
278+
__attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type, false);
263279
}
264280

265281
externvoid__detachInterrupt(uint8_tpin)
266282
{
267283
esp_intr_disable(gpio_intr_handle);
284+
if (__pinInterruptHandlers[pin].functional&&__pinInterruptHandlers[pin].arg)
285+
{
286+
cleanupFunctional(__pinInterruptHandlers[pin].arg);
287+
}
268288
__pinInterruptHandlers[pin].fn=NULL;
269289
__pinInterruptHandlers[pin].arg=NULL;
290+
__pinInterruptHandlers[pin].arg= false;
291+
270292
GPIO.pin[pin].int_ena=0;
271293
GPIO.pin[pin].int_type=0;
272294
esp_intr_enable(gpio_intr_handle);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include<Arduino.h>
2+
#include<FunctionalInterrupt.h>
3+
4+
#defineBUTTON116
5+
#defineBUTTON217
6+
7+
classButton
8+
{
9+
public:
10+
Button(uint8_t reqPin) : PIN(reqPin){
11+
pinMode(PIN, INPUT_PULLUP);
12+
attachInterrupt(PIN, std::bind(&Button::isr,this), FALLING);
13+
};
14+
~Button(){
15+
detachInterrupt(PIN);
16+
}
17+
18+
void IRAM_ATTR isr(){
19+
numberKeyPresses += 1;
20+
pressed = true;
21+
}
22+
23+
voidcheckPressed(){
24+
if (pressed){
25+
Serial.printf("Button on pin %u has been pressed %u times\n", PIN, numberKeyPresses);
26+
pressed = false;
27+
}
28+
}
29+
30+
private:
31+
constuint8_t PIN;
32+
volatileuint32_t numberKeyPresses;
33+
volatilebool pressed;
34+
};
35+
36+
Button button1(BUTTON1);
37+
Button button2(BUTTON2);
38+
39+
40+
voidsetup(){
41+
Serial.begin(115200);
42+
}
43+
44+
voidloop(){
45+
button1.checkPressed();
46+
button2.checkPressed();
47+
}

libraries/ESP32/examples/GPIOInterrupt/GPIOInterrupt.ino renamed to libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino

File renamed without changes.

0 commit comments

Comments
(0)