@@ -109,8 +109,9 @@ typedef void (*voidFuncPtrArg)(void*);
109109
110110typedef struct {
111111 uint8_t mode;
112- void (*fn)( void ) ;
112+ voidFuncPtr fn ;
113113 void * arg;
114+ bool functional;
114115} interrupt_handler_t ;
115116
116117// duplicate from functionalInterrupt.h keep in sync
@@ -125,11 +126,11 @@ typedef struct {
125126 void * functionInfo;
126127} ArgStructure;
127128
128- static interrupt_handler_t interrupt_handlers[16 ];
129+ static interrupt_handler_t interrupt_handlers[16 ] = { { 0 , 0 , 0 , 0 }, } ;
129130static uint32_t interrupt_reg = 0 ;
130131
131- void ICACHE_RAM_ATTR interrupt_handler (void *arg) {
132- ( void ) arg;
132+ void ICACHE_RAM_ATTR interrupt_handler (void *)
133+ {
133134 uint32_t status = GPIE;
134135 GPIEC = status;// clear them interrupts
135136 uint32_t levels = GPI;
@@ -144,34 +145,37 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
144145 if (handler->fn &&
145146 (handler->mode == CHANGE ||
146147 (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 ();
148+ // to make ISR compatible to Arduino AVR model where interrupts are disabled
149+ // we disable them before we call the client ISR
150+ uint32_t savedPS = xt_rsil (15 ); // stop other interrupts
151+ if (handler->functional )
152+ {
153+ ArgStructure* localArg = (ArgStructure*)handler->arg ;
154+ if (localArg && localArg->interruptInfo )
155+ {
156+ localArg->interruptInfo ->pin = i;
157+ localArg->interruptInfo ->value = __digitalRead (i);
158+ localArg->interruptInfo ->micro = micros ();
159+ }
160+ }
161+ if (handler->arg )
162+ {
163+ ((voidFuncPtrArg)handler->fn )(handler->arg );
164+ }
165+ else
166+ {
167+ handler->fn ();
168+ }
169+ xt_wsr_ps (savedPS);
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) {
174-
177+ extern void __attachInterruptFunctionalArg (uint8_t pin, voidFuncPtrArg userFunc, void * arg, int mode, bool functional)
178+ {
175179 // #5780
176180 // https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
177181 if ((uint32_t )userFunc >= 0x40200000 )
@@ -183,14 +187,15 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
183187
184188 if (pin < 16 ) {
185189 ETS_GPIO_INTR_DISABLE ();
186- interrupt_handler_t * handler = &interrupt_handlers[pin];
190+ interrupt_handler_t * handler = &interrupt_handlers[pin];
187191 handler->mode = mode;
188- handler->fn = userFunc;
189- if (handler->arg ) // Clean when new attach without detach
190- {
191- cleanupFunctional (handler->arg );
192- }
192+ handler->fn = (voidFuncPtr) userFunc;
193+ if (handler->functional && handler-> arg ) // Clean when new attach without detach
194+ {
195+ cleanupFunctional (handler->arg );
196+ }
193197 handler->arg = arg;
198+ handler->functional = functional;
194199 interrupt_reg |= (1 << pin);
195200 GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
196201 GPIEC = (1 << pin); // Clear Interrupt for this pin
@@ -200,28 +205,38 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
200205 }
201206}
202207
203- extern void ICACHE_RAM_ATTR __attachInterrupt (uint8_t pin, voidFuncPtr userFunc, int mode )
208+ extern void __attachInterruptArg (uint8_t pin, voidFuncPtrArg userFunc, void * arg, int mode)
204209{
205- __attachInterruptArg (pin, userFunc, 0 , mode);
210+ __attachInterruptFunctionalArg (pin, userFunc, arg , mode, false );
206211}
207212
208- extern 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- }
213+ extern void __attachInterrupt (uint8_t pin, voidFuncPtr userFunc, int mode)
214+ {
215+ __attachInterruptFunctionalArg (pin, (voidFuncPtrArg)userFunc, 0 , mode, false );
216+ }
217+
218+ extern void ICACHE_RAM_ATTR __detachInterrupt (uint8_t pin)
219+ {
220+ if (pin < 16 )
221+ {
222+ ETS_GPIO_INTR_DISABLE ();
223+ GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
224+ GPIEC = (1 << pin); // Clear Interrupt for this pin
225+ interrupt_reg &= ~(1 << pin);
226+ interrupt_handler_t * handler = &interrupt_handlers[pin];
227+ handler->mode = 0 ;
228+ handler->fn = 0 ;
229+ if (handler->functional && handler->arg )
230+ {
231+ cleanupFunctional (handler->arg );
232+ }
233+ handler->arg = 0 ;
234+ handler->functional = false ;
235+ if (interrupt_reg)
236+ {
237+ ETS_GPIO_INTR_ENABLE ();
238+ }
239+ }
225240}
226241
227242void initPins () {
@@ -243,6 +258,7 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
243258extern void digitalWrite (uint8_t pin, uint8_t val) __attribute__ ((weak, alias(" __digitalWrite" )));
244259extern int digitalRead (uint8_t pin) __attribute__ ((weak, alias(" __digitalRead" )));
245260extern void attachInterrupt (uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias(" __attachInterrupt" )));
261+ extern void attachInterruptArg (uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__((weak, alias(" __attachInterruptArg" )));
246262extern void detachInterrupt (uint8_t pin) __attribute__ ((weak, alias(" __detachInterrupt" )));
247263
248264};
0 commit comments