3535static void nothing (void ) {
3636}
3737
38- static volatile voidFuncPtr intFunc [EXTERNAL_NUM_INTERRUPTS ] = {
38+ static volatile voidFuncPtrParam intFunc [EXTERNAL_NUM_INTERRUPTS ] = {
3939#if EXTERNAL_NUM_INTERRUPTS > 8
4040 #warning There are more than 8 external interrupts. Some callbacks may not be initialized.
4141 nothing ,
@@ -65,11 +65,23 @@ static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = {
6565 nothing ,
6666#endif
6767};
68+ static volatile void * intFuncParam [EXTERNAL_NUM_INTERRUPTS ];
6869// volatile static voidFuncPtr twiIntFunc;
6970
70- void attachInterrupt (uint8_t interruptNum , void (* userFunc )(void ), int mode ) {
71+ void attachInterrupt (uint8_t interruptNum , voidFuncPtr userFunc , int mode ) {
72+ // THIS IMPLEMENTATION IS NOT PORTABLE!
73+ //
74+ // On AVR's calling convention, calling a function with more arguments than it declares
75+ // is OK - The extra parameter is ignored and causes no harm
76+ //
77+ // This implementation takes advantage of it to support callbacks with and without parameters with minimum overhead.
78+ attachInterruptParam (interruptNum , (voidFuncPtrParam )userFunc , mode , NULL );
79+ }
80+
81+ void attachInterruptParam (uint8_t interruptNum , voidFuncPtrParam userFunc , int mode , void * param ) {
7182 if (interruptNum < EXTERNAL_NUM_INTERRUPTS ) {
7283 intFunc [interruptNum ] = userFunc ;
84+ intFuncParam [interruptNum ] = param ;
7385
7486 // Configure the interrupt mode (trigger on low input, any change, rising
7587 // edge, or falling edge). The mode constants were chosen to correspond
@@ -271,6 +283,7 @@ void detachInterrupt(uint8_t interruptNum) {
271283 }
272284
273285 intFunc [interruptNum ] = nothing ;
286+ intFuncParam [interruptNum ] = 0 ;
274287 }
275288}
276289
@@ -280,75 +293,37 @@ void attachInterruptTwi(void (*userFunc)(void) ) {
280293}
281294*/
282295
283- #if defined(__AVR_ATmega32U4__ )
284- ISR (INT0_vect ) {
285- intFunc [EXTERNAL_INT_0 ]();
286- }
287-
288- ISR (INT1_vect ) {
289- intFunc [EXTERNAL_INT_1 ]();
290- }
291-
292- ISR (INT2_vect ) {
293- intFunc [EXTERNAL_INT_2 ]();
294- }
296+ #define IMPLEMENT_ISR (vect , interrupt ) \
297+ ISR(vect) { \
298+ intFunc[interrupt](intFuncParam [interrupt]); \
299+ }
295300
296- ISR (INT3_vect ) {
297- intFunc [EXTERNAL_INT_3 ]();
298- }
301+ #if defined(__AVR_ATmega32U4__ )
299302
300- ISR (INT6_vect ) {
301- intFunc [EXTERNAL_INT_4 ]();
302- }
303+ IMPLEMENT_ISR (INT0_vect , EXTERNAL_INT_0 )
304+ IMPLEMENT_ISR (INT1_vect , EXTERNAL_INT_1 )
305+ IMPLEMENT_ISR (INT2_vect , EXTERNAL_INT_2 )
306+ IMPLEMENT_ISR (INT3_vect , EXTERNAL_INT_3 )
307+ IMPLEMENT_ISR (INT6_vect , EXTERNAL_INT_4 )
303308
304309#elif defined(EICRA ) && defined(EICRB )
305310
306- ISR (INT0_vect ) {
307- intFunc [EXTERNAL_INT_2 ]();
308- }
309-
310- ISR (INT1_vect ) {
311- intFunc [EXTERNAL_INT_3 ]();
312- }
313-
314- ISR (INT2_vect ) {
315- intFunc [EXTERNAL_INT_4 ]();
316- }
317-
318- ISR (INT3_vect ) {
319- intFunc [EXTERNAL_INT_5 ]();
320- }
321-
322- ISR (INT4_vect ) {
323- intFunc [EXTERNAL_INT_0 ]();
324- }
325-
326- ISR (INT5_vect ) {
327- intFunc [EXTERNAL_INT_1 ]();
328- }
329-
330- ISR (INT6_vect ) {
331- intFunc [EXTERNAL_INT_6 ]();
332- }
333-
334- ISR (INT7_vect ) {
335- intFunc [EXTERNAL_INT_7 ]();
336- }
311+ IMPLEMENT_ISR (INT0_vect , EXTERNAL_INT_2 )
312+ IMPLEMENT_ISR (INT1_vect , EXTERNAL_INT_3 )
313+ IMPLEMENT_ISR (INT2_vect , EXTERNAL_INT_4 )
314+ IMPLEMENT_ISR (INT3_vect , EXTERNAL_INT_5 )
315+ IMPLEMENT_ISR (INT4_vect , EXTERNAL_INT_0 )
316+ IMPLEMENT_ISR (INT5_vect , EXTERNAL_INT_1 )
317+ IMPLEMENT_ISR (INT6_vect , EXTERNAL_INT_6 )
318+ IMPLEMENT_ISR (INT7_vect , EXTERNAL_INT_7 )
337319
338320#else
339321
340- ISR (INT0_vect ) {
341- intFunc [EXTERNAL_INT_0 ]();
342- }
343-
344- ISR (INT1_vect ) {
345- intFunc [EXTERNAL_INT_1 ]();
346- }
322+ IMPLEMENT_ISR (INT0_vect , EXTERNAL_INT_0 )
323+ IMPLEMENT_ISR (INT1_vect , EXTERNAL_INT_1 )
347324
348325#if defined(EICRA ) && defined(ISC20 )
349- ISR (INT2_vect ) {
350- intFunc [EXTERNAL_INT_2 ]();
351- }
326+ IMPLEMENT_ISR (INT2_vect , EXTERNAL_INT_2 )
352327#endif
353328
354329#endif
@@ -359,4 +334,3 @@ ISR(TWI_vect) {
359334 twiIntFunc();
360335}
361336*/
362-
0 commit comments