@@ -109,8 +109,9 @@ typedef void (*voidFuncPtrArg)(void*);
109
109
110
110
typedef struct {
111
111
uint8_t mode;
112
- void (*fn)( void ) ;
112
+ voidFuncPtr fn ;
113
113
void * arg;
114
+ bool functional;
114
115
} interrupt_handler_t ;
115
116
116
117
// duplicate from functionalInterrupt.h keep in sync
@@ -125,11 +126,11 @@ typedef struct {
125
126
void * functionInfo;
126
127
} ArgStructure;
127
128
128
- static interrupt_handler_t interrupt_handlers[16 ];
129
+ static interrupt_handler_t interrupt_handlers[16 ] = { { 0 , 0 , 0 , 0 }, } ;
129
130
static uint32_t interrupt_reg = 0 ;
130
131
131
- void ICACHE_RAM_ATTR interrupt_handler (void *arg) {
132
- ( void ) arg;
132
+ void ICACHE_RAM_ATTR interrupt_handler (void *)
133
+ {
133
134
uint32_t status = GPIE;
134
135
GPIEC = status;// clear them interrupts
135
136
uint32_t levels = GPI;
@@ -144,34 +145,37 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
144
145
if (handler->fn &&
145
146
(handler->mode == CHANGE ||
146
147
(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);
164
170
}
165
- xt_wsr_ps (savedPS);
166
- }
167
171
}
168
172
ETS_GPIO_INTR_ENABLE ();
169
173
}
170
174
171
175
extern void cleanupFunctional (void * arg);
172
176
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
+ {
175
179
// #5780
176
180
// https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
177
181
if ((uint32_t )userFunc >= 0x40200000 )
@@ -183,14 +187,15 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
183
187
184
188
if (pin < 16 ) {
185
189
ETS_GPIO_INTR_DISABLE ();
186
- interrupt_handler_t * handler = &interrupt_handlers[pin];
190
+ interrupt_handler_t * handler = &interrupt_handlers[pin];
187
191
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
+ }
193
197
handler->arg = arg;
198
+ handler->functional = functional;
194
199
interrupt_reg |= (1 << pin);
195
200
GPC (pin) &= ~(0xF << GPCI);// INT mode disabled
196
201
GPIEC = (1 << pin); // Clear Interrupt for this pin
@@ -200,28 +205,38 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
200
205
}
201
206
}
202
207
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)
204
209
{
205
- __attachInterruptArg (pin, userFunc, 0 , mode);
210
+ __attachInterruptFunctionalArg (pin, userFunc, arg , mode, false );
206
211
}
207
212
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
+ }
225
240
}
226
241
227
242
void initPins () {
@@ -243,6 +258,7 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
243
258
extern void digitalWrite (uint8_t pin, uint8_t val) __attribute__ ((weak, alias(" __digitalWrite" )));
244
259
extern int digitalRead (uint8_t pin) __attribute__ ((weak, alias(" __digitalRead" )));
245
260
extern 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" )));
246
262
extern void detachInterrupt (uint8_t pin) __attribute__ ((weak, alias(" __detachInterrupt" )));
247
263
248
264
};
0 commit comments