Skip to content

Commit ba0e049

Browse files
hreintkeigrr
authored andcommitted
Functional Interrupts initial
1 parent 3f5d06b commit ba0e049

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

cores/esp8266/FunctionalInterrupt.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <FunctionalInterrupt.h>
2+
3+
4+
// Duplicate typedefs from core_esp8266_wiring_digital_c
5+
typedef void (*voidFuncPtr)(void);
6+
7+
// Helper functions for Functional interrupt routines
8+
extern "C" void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void*fp , int mode);
9+
10+
// Structure for communication
11+
struct ArgStructure {
12+
std::function<void(void)> reqFunction;
13+
};
14+
15+
void interruptFunctional(void* arg)
16+
{
17+
((ArgStructure*)arg)->reqFunction();
18+
}
19+
20+
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
21+
{
22+
// use the local interrupt routine which takes the ArgStructure as argument
23+
__attachInterruptArg (pin, (voidFuncPtr)interruptFunctional, new ArgStructure{intRoutine}, mode);
24+
}

cores/esp8266/FunctionalInterrupt.h

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef FUNCTIONALINTERRUPT_H
2+
#define FUNCTIONALINTERRUPT_H
3+
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
#include <functional>
7+
8+
extern "C" {
9+
#include "c_types.h"
10+
#include "ets_sys.h"
11+
}
12+
13+
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
14+
15+
#endif //INTERRUPTS_H

cores/esp8266/core_esp8266_wiring_digital.c

+25-7
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,15 @@ extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) {
105105
*/
106106

107107
typedef void (*voidFuncPtr)(void);
108+
typedef void (*voidFuncPtrArg)(void*);
108109

109110
typedef struct {
110111
uint8_t mode;
111112
void (*fn)(void);
113+
void * arg;
112114
} interrupt_handler_t;
113115

116+
114117
static interrupt_handler_t interrupt_handlers[16];
115118
static uint32_t interrupt_reg = 0;
116119

@@ -127,31 +130,44 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
127130
while(!(changedbits & (1 << i))) i++;
128131
changedbits &= ~(1 << i);
129132
interrupt_handler_t *handler = &interrupt_handlers[i];
130-
if (handler->fn &&
131-
(handler->mode == CHANGE ||
133+
if (handler->fn &&
134+
(handler->mode == CHANGE ||
132135
(handler->mode & 1) == !!(levels & (1 << i)))) {
133136
// to make ISR compatible to Arduino AVR model where interrupts are disabled
134137
// we disable them before we call the client ISR
135-
uint32_t savedPS = xt_rsil(15); // stop other interrupts
136-
handler->fn();
137-
xt_wsr_ps(savedPS);
138+
uint32_t savedPS = xt_rsil(15); // stop other interrupts
139+
if (handler->arg)
140+
{
141+
((voidFuncPtrArg)handler->fn)(handler->arg);
142+
}
143+
else
144+
{
145+
handler->fn();
146+
}
147+
xt_wsr_ps(savedPS);
138148
}
139149
}
140150
ETS_GPIO_INTR_ENABLE();
141151
}
142152

143-
extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode) {
153+
extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void *arg, int mode) {
144154
if(pin < 16) {
145155
interrupt_handler_t *handler = &interrupt_handlers[pin];
146156
handler->mode = mode;
147157
handler->fn = userFunc;
158+
handler->arg = arg;
148159
interrupt_reg |= (1 << pin);
149160
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
150161
GPIEC = (1 << pin); //Clear Interrupt for this pin
151162
GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode"
152163
}
153164
}
154165

166+
extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode )
167+
{
168+
__attachInterruptArg (pin, userFunc, 0, mode);
169+
}
170+
155171
extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) {
156172
if(pin < 16) {
157173
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
@@ -160,6 +176,7 @@ extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) {
160176
interrupt_handler_t *handler = &interrupt_handlers[pin];
161177
handler->mode = 0;
162178
handler->fn = 0;
179+
handler->arg = 0;
163180
}
164181
}
165182

@@ -176,7 +193,7 @@ void initPins() {
176193
for (int i = 12; i <= 16; ++i) {
177194
pinMode(i, INPUT);
178195
}
179-
196+
180197
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
181198
ETS_GPIO_INTR_ENABLE();
182199
}
@@ -186,3 +203,4 @@ extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("
186203
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
187204
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
188205
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
206+

0 commit comments

Comments
 (0)