Skip to content

Commit 938a266

Browse files
Add enableInterrupt and disableInterrupt
These allow temporarily enabling and disabling a single interrupt. This is currently pretty much the same as detaching and re-attaching the interrupt, but this will change when attachInterrupt is changed to clear any pending interrupts next. This commit introduces duplicate code, between attach/detach and enable/disable, which will be removed next (doing this in one commit makes the diff harder to review).
1 parent 90e3a08 commit 938a266

File tree

4 files changed

+188
-0
lines changed

4 files changed

+188
-0
lines changed

hardware/arduino/avr/cores/arduino/Arduino.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
140140

141141
void attachInterrupt(uint8_t, void (*)(void), int mode);
142142
void detachInterrupt(uint8_t);
143+
void enableInterrupt(uint8_t interruptNum);
144+
void disableInterrupt(uint8_t interruptNum);
143145

144146
void setup(void);
145147
void loop(void);

hardware/arduino/avr/cores/arduino/WInterrupts.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,94 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
152152
}
153153
}
154154

155+
void enableInterrupt(uint8_t interruptNum) {
156+
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
157+
158+
// Enable the interrupt.
159+
switch (interruptNum) {
160+
#if defined(__AVR_ATmega32U4__)
161+
// I hate doing this, but the register assignment differs between the 1280/2560
162+
// and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
163+
// even present on the 32U4 this is the only way to distinguish between them.
164+
case 0:
165+
EIMSK |= (1<<INT0);
166+
break;
167+
case 1:
168+
EIMSK |= (1<<INT1);
169+
break;
170+
case 2:
171+
EIMSK |= (1<<INT2);
172+
break;
173+
case 3:
174+
EIMSK |= (1<<INT3);
175+
break;
176+
case 4:
177+
EIMSK |= (1<<INT6);
178+
break;
179+
#elif defined(EIFR) && defined(EICRB) && defined(EIMSK)
180+
case 2:
181+
EIMSK |= (1 << INT0);
182+
break;
183+
case 3:
184+
EIMSK |= (1 << INT1);
185+
break;
186+
case 4:
187+
EIMSK |= (1 << INT2);
188+
break;
189+
case 5:
190+
EIMSK |= (1 << INT3);
191+
break;
192+
case 0:
193+
EIMSK |= (1 << INT4);
194+
break;
195+
case 1:
196+
EIMSK |= (1 << INT5);
197+
break;
198+
case 6:
199+
EIMSK |= (1 << INT6);
200+
break;
201+
case 7:
202+
EIMSK |= (1 << INT7);
203+
break;
204+
#else
205+
case 0:
206+
#if defined(ISC00) && defined(EIMSK)
207+
EIMSK |= (1 << INT0);
208+
#elif defined(ISC00) && defined(GICR)
209+
GICR |= (1 << INT0);
210+
#elif defined(ISC00) && defined(GIMSK)
211+
GIMSK |= (1 << INT0);
212+
#else
213+
#error attachInterrupt not finished for this CPU (case 0)
214+
#endif
215+
break;
216+
217+
case 1:
218+
#if defined(ISC10) && defined(ISC11) && defined(EIMSK)
219+
EIMSK |= (1 << INT1);
220+
#elif defined(ISC10) && defined(ISC11) && defined(GICR)
221+
GICR |= (1 << INT1);
222+
#elif defined(ISC10) && defined(GIMSK) && defined(GIMSK)
223+
GIMSK |= (1 << INT1);
224+
#else
225+
#warning attachInterrupt may need some more work for this cpu (case 1)
226+
#endif
227+
break;
228+
229+
case 2:
230+
#if defined(ISC20) && defined(ISC21) && defined(EIMSK)
231+
EIMSK |= (1 << INT2);
232+
#elif defined(ISC20) && defined(ISC21) && defined(GICR)
233+
GICR |= (1 << INT2);
234+
#elif defined(ISC20) && defined(GIMSK) && defined(GIMSK)
235+
GIMSK |= (1 << INT2);
236+
#endif
237+
break;
238+
#endif
239+
}
240+
}
241+
}
242+
155243
void detachInterrupt(uint8_t interruptNum) {
156244
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
157245
// Disable the interrupt. (We can't assume that interruptNum is equal
@@ -230,6 +318,82 @@ void detachInterrupt(uint8_t interruptNum) {
230318
}
231319
}
232320

321+
void disableInterrupt(uint8_t interruptNum) {
322+
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
323+
// Disable the interrupt. (We can't assume that interruptNum is equal
324+
// to the number of the EIMSK bit to clear, as this isn't true on the
325+
// ATmega8. There, INT0 is 6 and INT1 is 7.)
326+
switch (interruptNum) {
327+
#if defined(__AVR_ATmega32U4__)
328+
case 0:
329+
EIMSK &= ~(1<<INT0);
330+
break;
331+
case 1:
332+
EIMSK &= ~(1<<INT1);
333+
break;
334+
case 2:
335+
EIMSK &= ~(1<<INT2);
336+
break;
337+
case 3:
338+
EIMSK &= ~(1<<INT3);
339+
break;
340+
case 4:
341+
EIMSK &= ~(1<<INT6);
342+
break;
343+
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
344+
case 2:
345+
EIMSK &= ~(1 << INT0);
346+
break;
347+
case 3:
348+
EIMSK &= ~(1 << INT1);
349+
break;
350+
case 4:
351+
EIMSK &= ~(1 << INT2);
352+
break;
353+
case 5:
354+
EIMSK &= ~(1 << INT3);
355+
break;
356+
case 0:
357+
EIMSK &= ~(1 << INT4);
358+
break;
359+
case 1:
360+
EIMSK &= ~(1 << INT5);
361+
break;
362+
case 6:
363+
EIMSK &= ~(1 << INT6);
364+
break;
365+
case 7:
366+
EIMSK &= ~(1 << INT7);
367+
break;
368+
#else
369+
case 0:
370+
#if defined(EIMSK) && defined(INT0)
371+
EIMSK &= ~(1 << INT0);
372+
#elif defined(GICR) && defined(ISC00)
373+
GICR &= ~(1 << INT0); // atmega32
374+
#elif defined(GIMSK) && defined(INT0)
375+
GIMSK &= ~(1 << INT0);
376+
#else
377+
#error detachInterrupt not finished for this cpu
378+
#endif
379+
break;
380+
381+
case 1:
382+
#if defined(EIMSK) && defined(INT1)
383+
EIMSK &= ~(1 << INT1);
384+
#elif defined(GICR) && defined(INT1)
385+
GICR &= ~(1 << INT1); // atmega32
386+
#elif defined(GIMSK) && defined(INT1)
387+
GIMSK &= ~(1 << INT1);
388+
#else
389+
#warning detachInterrupt may need some more work for this cpu (case 1)
390+
#endif
391+
break;
392+
#endif
393+
}
394+
}
395+
}
396+
233397
/*
234398
void attachInterruptTwi(void (*userFunc)(void) ) {
235399
twiIntFunc = userFunc;

hardware/arduino/sam/cores/arduino/WInterrupts.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode)
119119
pio->PIO_IER = mask;
120120
}
121121

122+
void enableInterrupt(uint32_t pin)
123+
{
124+
Pio *pio = g_APinDescription[pin].pPort;
125+
uint32_t mask = g_APinDescription[pin].ulPin;
126+
127+
// Enable interrupt
128+
pio->PIO_IER = mask;
129+
}
130+
122131
void detachInterrupt(uint32_t pin)
123132
{
124133
// Retrieve pin information
@@ -129,6 +138,16 @@ void detachInterrupt(uint32_t pin)
129138
pio->PIO_IDR = mask;
130139
}
131140

141+
void disableInterrupt(uint32_t pin)
142+
{
143+
// Retrieve pin information
144+
Pio *pio = g_APinDescription[pin].pPort;
145+
uint32_t mask = g_APinDescription[pin].ulPin;
146+
147+
// Disable interrupt
148+
pio->PIO_IDR = mask;
149+
}
150+
132151
#ifdef __cplusplus
133152
extern "C" {
134153
#endif

hardware/arduino/sam/cores/arduino/WInterrupts.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode);
2929

3030
void detachInterrupt(uint32_t pin);
3131

32+
void enableInterrupt(uint32_t pin);
33+
void disableInterrupt(uint32_t pin);
34+
3235
#ifdef __cplusplus
3336
}
3437
#endif

0 commit comments

Comments
 (0)