Skip to content

Commit 3e4e6f9

Browse files
committed
Added ISR_DEFERRED option for attachInterrupt() to defer callback from ISR context
1 parent 01a9273 commit 3e4e6f9

File tree

5 files changed

+65
-2
lines changed

5 files changed

+65
-2
lines changed

changelog.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
- InternalFS use LittleFS to manage internal flash for bonding and other user data
1414
- ExternalFS use fatfs to manage external spi flash (nrf52840 only) for usb msc.
1515
- Replace cpritnf by std printf
16-
- Add HwPWM3 for nRF52840
16+
- Added HwPWM3 for nRF52840
17+
- Added ISR_DEFERRED for attachInterrupt() for deferring callback from ISR context
18+
- Added digital_interrupt_deferred sketch for demo
1719

1820
## 0.8.6
1921

cores/nRF5/WInterrupts.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#endif
3232

3333
static voidFuncPtr callbacksInt[NUMBER_OF_GPIO_TE];
34+
static bool callbackDeferred[NUMBER_OF_GPIO_TE];
3435
static int8_t channelMap[NUMBER_OF_GPIO_TE];
3536
static int enabled = 0;
3637

@@ -39,6 +40,7 @@ static void __initialize()
3940
{
4041
memset(callbacksInt, 0, sizeof(callbacksInt));
4142
memset(channelMap, -1, sizeof(channelMap));
43+
memset(callbackDeferred, 0, sizeof(callbackDeferred));
4244

4345
NVIC_DisableIRQ(GPIOTE_IRQn);
4446
NVIC_ClearPendingIRQ(GPIOTE_IRQn);
@@ -65,6 +67,9 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
6567

6668
pin = g_ADigitalPinMap[pin];
6769

70+
bool deferred = (mode & ISR_DEFERRED) ? true : false;
71+
mode &= ~ISR_DEFERRED;
72+
6873
uint32_t polarity;
6974

7075
switch (mode) {
@@ -88,6 +93,7 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
8893
if (channelMap[ch] == -1 || (uint32_t)channelMap[ch] == pin) {
8994
channelMap[ch] = pin;
9095
callbacksInt[ch] = callback;
96+
callbackDeferred[ch] = deferred;
9197

9298
NRF_GPIOTE->CONFIG[ch] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk);
9399
NRF_GPIOTE->CONFIG[ch] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
@@ -119,6 +125,7 @@ void detachInterrupt(uint32_t pin)
119125
if ((uint32_t)channelMap[ch] == pin) {
120126
channelMap[ch] = -1;
121127
callbacksInt[ch] = NULL;
128+
callbackDeferred[ch] = false;
122129

123130
NRF_GPIOTE->CONFIG[ch] &= ~GPIOTE_CONFIG_MODE_Event;
124131

@@ -136,7 +143,12 @@ void GPIOTE_IRQHandler()
136143
for (int ch = 0; ch < NUMBER_OF_GPIO_TE; ch++) {
137144
if ((*(uint32_t *)((uint32_t)NRF_GPIOTE + event) == 0x1UL) && (NRF_GPIOTE->INTENSET & (1 << ch))) {
138145
if (channelMap[ch] != -1 && callbacksInt[ch]) {
139-
callbacksInt[ch]();
146+
if ( callbackDeferred[ch] ) {
147+
// Adafruit defer callback to non-isr if configured so
148+
ada_callback_fromISR(NULL, callbacksInt[ch]);
149+
}else{
150+
callbacksInt[ch]();
151+
}
140152
}
141153

142154
*(uint32_t *)((uint32_t)NRF_GPIOTE + event) = 0;

cores/nRF5/WInterrupts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ extern "C" {
3131
#define FALLING 3
3232
#define RISING 4
3333

34+
#define ISR_DEFERRED 0x0100
35+
3436
#define DEFAULT 1
3537
#define EXTERNAL 0
3638

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,4 @@ PIN_SPI_SCK LITERAL1
124124
PIN_WIRE_SDA LITERAL1
125125
PIN_WIRE_SCL LITERAL1
126126

127+
ISR_DEFERRED LITERAL1
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*********************************************************************
2+
This is an example for our Feather Bluefruit modules
3+
4+
Pick one up today in the adafruit shop!
5+
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
MIT license, check LICENSE for more information
11+
All text above, and the splash screen below must be included in
12+
any redistribution
13+
*********************************************************************/
14+
15+
/*
16+
* This sketch demotrate how to pass ISR_DEFFERED as additional parameter
17+
* to defer callback from ISR context with attachInterrupt
18+
*/
19+
#include <Arduino.h>
20+
21+
int interruptPin = A0;
22+
23+
void setup()
24+
{
25+
Serial.begin(115200);
26+
27+
pinMode(interruptPin, INPUT_PULLUP);
28+
29+
// ISR_DEFERRED flag cause the callback to be deferred from ISR context
30+
// and invoked within a callback thread.
31+
// It is required to use ISR_DEFERRED if callback function take long time
32+
// to run e.g Serial.print() or using any of Bluefruit API() which will
33+
// potentially call rtos API
34+
attachInterrupt(interruptPin, digital_callback, ISR_DEFERRED | CHANGE);
35+
}
36+
37+
void loop()
38+
{
39+
// nothing to do
40+
}
41+
42+
void digital_callback(void)
43+
{
44+
Serial.print("Pin value: ");
45+
Serial.println(digitalRead(interruptPin));
46+
}

0 commit comments

Comments
 (0)