Skip to content

Commit 1c90673

Browse files
committed
Ensure config is written before enabling the corresponding interrupt enable flag
1 parent cbbc57b commit 1c90673

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

cores/nRF5/WInterrupts.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,23 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
111111
// to preferably re-use any channel that was already in use (even if
112112
// earlier channel is no longer in use).
113113
for (int ch = 0; ch < NUMBER_OF_GPIO_TE; ch++) {
114-
if ((uint32_t)channelMap[ch] == pin) {
115-
// The pin is already allocated in the channelMap
116-
// update the polarity (when events fire) and callbacks
117-
// However, do NOT clear any GPIOTE events
118-
uint32_t tmp = NRF_GPIOTE->CONFIG[ch];
119-
channelMap[ch] = pin;
120-
callbacksInt[ch] = callback;
121-
callbackDeferred[ch] = deferred;
122-
tmp &= oldRegMask;
123-
tmp |= newRegBits;
124-
NRF_GPIOTE->CONFIG[ch] = tmp;
125-
NRF_GPIOTE->INTENSET = (1 << ch); // old code did this ... no harm in ensuring this is set
126-
return (1 << ch);
127-
}
114+
// skip if the channel was not already assigned to this pin
115+
if ((uint32_t)channelMap[ch] != pin) continue;
116+
117+
// The pin is already allocated in the channelMap
118+
// update the polarity (when events fire) and callbacks
119+
// However, do NOT clear any GPIOTE events
120+
uint32_t tmp = NRF_GPIOTE->CONFIG[ch];
121+
channelMap[ch] = pin;
122+
callbacksInt[ch] = callback;
123+
callbackDeferred[ch] = deferred;
124+
tmp &= oldRegMask;
125+
tmp |= newRegBits;
126+
NRF_GPIOTE->CONFIG[ch] = tmp;
127+
asm volatile ("" : : : "memory");
128+
__asm__ __volatile__ ("nop\n\tnop\n\tnop\n\tnop\n");
129+
NRF_GPIOTE->INTENSET = (1 << ch); // old code did this ... no harm in ensuring this is set
130+
return (1 << ch);
128131
}
129132

130133
// When the pin isn't already configured for interrupts, then attempt to
@@ -135,6 +138,7 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
135138
if (channelMap[ch] != -1) continue;
136139
// skip if channel is not disabled (e.g., in use by some other component or library)
137140
if (nrf_gpiote_te_is_enabled(NRF_GPIOTE, ch)) continue;
141+
138142
// clear any old events on this GPIOTE channel
139143
NRF_GPIOTE->EVENTS_IN[ch] = 0;
140144
uint32_t tmp = NRF_GPIOTE->CONFIG[ch];
@@ -145,6 +149,8 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
145149
tmp |= newRegBits;
146150
// TODO: make check/set for new channel an atomic operation
147151
NRF_GPIOTE->CONFIG[ch] = tmp;
152+
asm volatile ("" : : : "memory");
153+
__asm__ __volatile__ ("nop\n\tnop\n\tnop\n\tnop\n");
148154
NRF_GPIOTE->INTENSET = (1 << ch);
149155
return (1 << ch);
150156
}

0 commit comments

Comments
 (0)