Functional interrupt (#1728)
* Initial * Implementation * Add to CMakelist.txt * Add example * Add IRAM_ATTR
This commit is contained in:
parent
5be3078b76
commit
ea61563c69
@ -17,6 +17,7 @@ set(CORE_SRCS
|
|||||||
cores/esp32/esp32-hal-touch.c
|
cores/esp32/esp32-hal-touch.c
|
||||||
cores/esp32/esp32-hal-uart.c
|
cores/esp32/esp32-hal-uart.c
|
||||||
cores/esp32/Esp.cpp
|
cores/esp32/Esp.cpp
|
||||||
|
cores/esp32/FunctionalInterrupt.cpp
|
||||||
cores/esp32/HardwareSerial.cpp
|
cores/esp32/HardwareSerial.cpp
|
||||||
cores/esp32/IPAddress.cpp
|
cores/esp32/IPAddress.cpp
|
||||||
cores/esp32/IPv6Address.cpp
|
cores/esp32/IPv6Address.cpp
|
||||||
|
44
cores/esp32/FunctionalInterrupt.cpp
Normal file
44
cores/esp32/FunctionalInterrupt.cpp
Normal file
@ -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 __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR interruptFunctional(void* arg)
|
||||||
|
{
|
||||||
|
InterruptArgStructure* localArg = (InterruptArgStructure*)arg;
|
||||||
|
if (localArg->interruptFunction)
|
||||||
|
{
|
||||||
|
localArg->interruptFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
|
||||||
|
{
|
||||||
|
// use the local interrupt routine which takes the ArgStructure as argument
|
||||||
|
__attachInterruptFunctionalArg (pin, (voidFuncPtrArg)interruptFunctional, new InterruptArgStructure{intRoutine}, mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void cleanupFunctional(void* arg)
|
||||||
|
{
|
||||||
|
delete (InterruptArgStructure*)arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
20
cores/esp32/FunctionalInterrupt.h
Normal file
20
cores/esp32/FunctionalInterrupt.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* FunctionalInterrupt.h
|
||||||
|
*
|
||||||
|
* Created on: 8 jul. 2018
|
||||||
|
* Author: Herman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CORE_CORE_FUNCTIONALINTERRUPT_H_
|
||||||
|
#define CORE_CORE_FUNCTIONALINTERRUPT_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct InterruptArgStructure {
|
||||||
|
std::function<void(void)> interruptFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CORE_CORE_FUNCTIONALINTERRUPT_H_ */
|
@ -74,6 +74,7 @@ typedef void (*voidFuncPtrArg)(void*);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
voidFuncPtr fn;
|
voidFuncPtr fn;
|
||||||
void* arg;
|
void* arg;
|
||||||
|
bool functional;
|
||||||
} InterruptHandle_t;
|
} InterruptHandle_t;
|
||||||
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
|
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;
|
static bool interrupt_initialized = false;
|
||||||
|
|
||||||
if(!interrupt_initialized) {
|
if(!interrupt_initialized) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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].fn = (voidFuncPtr)userFunc;
|
||||||
__pinInterruptHandlers[pin].arg = arg;
|
__pinInterruptHandlers[pin].arg = arg;
|
||||||
|
__pinInterruptHandlers[pin].functional = functional;
|
||||||
|
|
||||||
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;
|
||||||
@ -258,15 +269,26 @@ extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * ar
|
|||||||
esp_intr_enable(gpio_intr_handle);
|
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) {
|
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)
|
extern void __detachInterrupt(uint8_t pin)
|
||||||
{
|
{
|
||||||
esp_intr_disable(gpio_intr_handle);
|
esp_intr_disable(gpio_intr_handle);
|
||||||
|
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||||
|
{
|
||||||
|
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||||
|
}
|
||||||
__pinInterruptHandlers[pin].fn = NULL;
|
__pinInterruptHandlers[pin].fn = NULL;
|
||||||
__pinInterruptHandlers[pin].arg = NULL;
|
__pinInterruptHandlers[pin].arg = NULL;
|
||||||
|
__pinInterruptHandlers[pin].arg = false;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include <FunctionalInterrupt.h>
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user