2626#include " ets_sys.h"
2727#include " user_interface.h"
2828#include " core_esp8266_waveform.h"
29+ #include " interrupts.h"
2930
3031extern " C" {
3132
@@ -109,8 +110,9 @@ typedef void (*voidFuncPtrArg)(void*);
109110
110111typedef struct {
111112 uint8_t mode;
112- void (*fn)( void ) ;
113+ voidFuncPtr fn ;
113114 void * arg;
115+ bool functional;
114116} interrupt_handler_t ;
115117
116118// duplicate from functionalInterrupt.h keep in sync
@@ -125,11 +127,11 @@ typedef struct {
125127 void * functionInfo;
126128} ArgStructure;
127129
128- static interrupt_handler_t interrupt_handlers[16 ];
130+ static interrupt_handler_t interrupt_handlers[16 ] = { { 0 , 0 , 0 , 0 }, } ;
129131static uint32_t interrupt_reg = 0 ;
130132
131- void ICACHE_RAM_ATTR interrupt_handler (void *arg) {
132- ( void ) arg;
133+ void ICACHE_RAM_ATTR interrupt_handler (void *)
134+ {
133135 uint32_t status = GPIE;
134136 GPIEC = status;// clear them interrupts
135137 uint32_t levels = GPI;
@@ -144,34 +146,49 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
144146 if (handler->fn &&
145147 (handler->mode == CHANGE ||
146148 (handler->mode & 1 ) == !!(levels & (1 << i)))) {
147- // to make ISR compatible to Arduino AVR model where interrupts are disabled
148- // we disable them before we call the client ISR
149- uint32_t savedPS = xt_rsil (15 ); // stop other interrupts
150- ArgStructure* localArg = (ArgStructure*)handler->arg ;
151- if (localArg && localArg->interruptInfo )
152- {
153- localArg->interruptInfo ->pin = i;
154- localArg->interruptInfo ->value = __digitalRead (i);
155- localArg->interruptInfo ->micro = micros ();
156- }
157- if (handler->arg )
158- {
159- ((voidFuncPtrArg)handler->fn )(handler->arg );
160- }
161- else
162- {
163- handler->fn ();
149+ // to make ISR compatible to Arduino AVR model where interrupts are disabled
150+ // we disable them before we call the client ISR
151+ esp8266::InterruptLock irqLock; // stop other interrupts
152+ if (handler->functional )
153+ {
154+ ArgStructure* localArg = (ArgStructure*)handler->arg ;
155+ if (localArg && localArg->interruptInfo )
156+ {
157+ localArg->interruptInfo ->pin = i;
158+ localArg->interruptInfo ->value = __digitalRead (i);
159+ localArg->interruptInfo ->micro = micros ();
160+ }
161+ }
162+ if (handler->arg )
163+ {
164+ ((voidFuncPtrArg)handler->fn )(handler->arg );
165+ }
166+ else
167+ {
168+ handler->fn ();
169+ }
164170 }
165- xt_wsr_ps (savedPS);
166- }
167171 }
168172 ETS_GPIO_INTR_ENABLE ();
169173}
170174
171175extern void cleanupFunctional (void * arg);
172176
173- extern void ICACHE_RAM_ATTR __attachInterruptArg (uint8_t pin, voidFuncPtr userFunc, void *arg, int mode) {
177+ static void set_interrupt_handlers (uint8_t pin, voidFuncPtr userFunc, void * arg, uint8_t mode, bool functional)
178+ {
179+ interrupt_handler_t * handler = &interrupt_handlers[pin];
180+ handler->mode = mode;
181+ handler->fn = userFunc;
182+ if (handler->functional && handler->arg ) // Clean when new attach without detach
183+ {
184+ cleanupFunctional (handler->arg );
185+ }
186+ handler->arg = arg;
187+ handler->functional = functional;
188+ }
174189
190+ extern void __attachInterruptFunctionalArg (uint8_t pin, voidFuncPtrArg userFunc, void * arg, int mode, bool functional)
191+ {
175192 // #5780
176193 // https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
177194 if ((uint32_t )userFunc >= 0x40200000 )
@@ -183,14 +200,7 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
183200
184201 if (pin < 16 ) {
185202 ETS_GPIO_INTR_DISABLE ();
186- interrupt_handler_t *handler = &interrupt_handlers[pin];
187- handler->mode = mode;
188- handler->fn = userFunc;
189- if (handler->arg ) // Clean when new attach without detach
190- {
191- cleanupFunctional (handler->arg );
192- }
193- handler->arg = arg;
203+ set_interrupt_handlers (pin, (voidFuncPtr)userFunc, arg, mode, functional);
194204 interrupt_reg |= (1 << pin);
195205 GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
196206 GPIEC = (1 << pin); // Clear Interrupt for this pin
@@ -200,31 +210,32 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
200210 }
201211}
202212
203- extern void ICACHE_RAM_ATTR __attachInterrupt (uint8_t pin, voidFuncPtr userFunc, int mode )
213+ extern void __attachInterruptArg (uint8_t pin, voidFuncPtrArg userFunc, void * arg, int mode)
204214{
205- __attachInterruptArg (pin, userFunc, 0 , mode);
215+ __attachInterruptFunctionalArg (pin, userFunc, arg , mode, false );
206216}
207217
208218extern void ICACHE_RAM_ATTR __detachInterrupt (uint8_t pin) {
209- if (pin < 16 ) {
210- ETS_GPIO_INTR_DISABLE ();
211- GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
212- GPIEC = (1 << pin); // Clear Interrupt for this pin
213- interrupt_reg &= ~(1 << pin);
214- interrupt_handler_t *handler = &interrupt_handlers[pin];
215- handler->mode = 0 ;
216- handler->fn = 0 ;
217- if (handler->arg )
218- {
219- cleanupFunctional (handler->arg );
220- }
221- handler->arg = 0 ;
222- if (interrupt_reg)
223- ETS_GPIO_INTR_ENABLE ();
224- }
219+ if (pin < 16 )
220+ {
221+ ETS_GPIO_INTR_DISABLE ();
222+ GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
223+ GPIEC = (1 << pin); // Clear Interrupt for this pin
224+ interrupt_reg &= ~(1 << pin);
225+ set_interrupt_handlers (pin, nullptr , nullptr , 0 , false );
226+ if (interrupt_reg)
227+ {
228+ ETS_GPIO_INTR_ENABLE ();
229+ }
230+ }
231+ }
232+
233+ extern void __attachInterrupt (uint8_t pin, voidFuncPtr userFunc, int mode)
234+ {
235+ __attachInterruptFunctionalArg (pin, (voidFuncPtrArg)userFunc, 0 , mode, false );
225236}
226237
227- void initPins () {
238+ extern void initPins () {
228239 // Disable UART interrupts
229240 system_set_os_print (0 );
230241 U0IE = 0 ;
@@ -243,6 +254,7 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
243254extern void digitalWrite (uint8_t pin, uint8_t val) __attribute__ ((weak, alias(" __digitalWrite" )));
244255extern int digitalRead (uint8_t pin) __attribute__ ((weak, alias(" __digitalRead" )));
245256extern void attachInterrupt (uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias(" __attachInterrupt" )));
257+ extern void attachInterruptArg (uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__((weak, alias(" __attachInterruptArg" )));
246258extern void detachInterrupt (uint8_t pin) __attribute__ ((weak, alias(" __detachInterrupt" )));
247259
248260};
0 commit comments