|
32 | 32 |
|
33 | 33 | #include "wiring_private.h"
|
34 | 34 |
|
35 |
| -static void nothing(void) { |
| 35 | +typedef void (*voidFuncPtrParam)(void*); |
| 36 | + |
| 37 | +static void nothing(void* arg) { |
36 | 38 | }
|
37 | 39 |
|
38 |
| -static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = { |
| 40 | +static volatile voidFuncPtrParam intFunc[EXTERNAL_NUM_INTERRUPTS] = { |
39 | 41 | #if EXTERNAL_NUM_INTERRUPTS > 8
|
40 | 42 | #warning There are more than 8 external interrupts. Some callbacks may not be initialized.
|
41 | 43 | nothing,
|
@@ -65,10 +67,20 @@ static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = {
|
65 | 67 | nothing,
|
66 | 68 | #endif
|
67 | 69 | };
|
| 70 | +static volatile void* intFuncParam[EXTERNAL_NUM_INTERRUPTS]; |
68 | 71 |
|
69 | 72 | void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
|
| 73 | + // To support callbacks with and without parameters with minimum overhead, |
| 74 | + // this relies on that fact that in C calling conventions extra argument on a |
| 75 | + // function call are safely ignored without side-effects. |
| 76 | + |
| 77 | + attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, NULL); |
| 78 | +} |
| 79 | + |
| 80 | + void attachInterruptParam(uint8_t interruptNum, voidFuncPtrParam userFunc, int mode, void* param) { |
70 | 81 | if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
|
71 | 82 | intFunc[interruptNum] = userFunc;
|
| 83 | + intFuncParam[interruptNum] = param; |
72 | 84 |
|
73 | 85 | // Configure the interrupt mode (trigger on low input, any change, rising
|
74 | 86 | // edge, or falling edge). The mode constants were chosen to correspond
|
@@ -270,13 +282,14 @@ void detachInterrupt(uint8_t interruptNum) {
|
270 | 282 | }
|
271 | 283 |
|
272 | 284 | intFunc[interruptNum] = nothing;
|
| 285 | + intFuncParam[interruptNum] = NULL; |
273 | 286 | }
|
274 | 287 | }
|
275 | 288 |
|
276 | 289 |
|
277 | 290 | #define IMPLEMENT_ISR(vect, interrupt) \
|
278 | 291 | ISR(vect) { \
|
279 |
| - intFunc[interrupt](); \ |
| 292 | + intFunc[interrupt]((void*)intFuncParam[interrupt]); \ |
280 | 293 | }
|
281 | 294 |
|
282 | 295 | #if defined(__AVR_ATmega32U4__)
|
|
0 commit comments