forked from espressif/arduino-esp32
Functional interrupt (#1728)
* Initial * Implementation * Add to CMakelist.txt * Add example * Add IRAM_ATTR
This commit is contained in:
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 {
|
||||
voidFuncPtr fn;
|
||||
void* arg;
|
||||
bool functional;
|
||||
} InterruptHandle_t;
|
||||
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;
|
||||
|
||||
|
||||
if(!interrupt_initialized) {
|
||||
interrupt_initialized = true;
|
||||
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].arg = arg;
|
||||
__pinInterruptHandlers[pin].functional = functional;
|
||||
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
__attachInterruptArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type);
|
||||
__attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type, false);
|
||||
}
|
||||
|
||||
extern void __detachInterrupt(uint8_t pin)
|
||||
{
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||
{
|
||||
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||
}
|
||||
__pinInterruptHandlers[pin].fn = NULL;
|
||||
__pinInterruptHandlers[pin].arg = NULL;
|
||||
__pinInterruptHandlers[pin].arg = false;
|
||||
|
||||
GPIO.pin[pin].int_ena = 0;
|
||||
GPIO.pin[pin].int_type = 0;
|
||||
esp_intr_enable(gpio_intr_handle);
|
||||
|
Reference in New Issue
Block a user