Skip to content

Commit 280ecaf

Browse files
committed
Three bugs fixed
* First loop should not be checking pinmap for -1. * Second loop should ensure no pending event when first allocating the GPIOTE channel. * Second loop needs to update pinmap with pin when allocated the GPIOTE channel.
1 parent 9d47073 commit 280ecaf

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

cores/nRF5/WInterrupts.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,18 @@ 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 || channelMap[ch] == -1) {
114+
if ((uint32_t)channelMap[ch] == pin) {
115115
// The pin is already allocated in the channelMap
116116
// update the polarity (when events fire) and callbacks
117+
// However, do NOT clear any GPIOTE events
117118
uint32_t tmp = NRF_GPIOTE->CONFIG[ch];
119+
channelMap[ch] = pin;
120+
callbacksInt[ch] = callback;
121+
callbackDeferred[ch] = deferred;
118122
tmp &= oldRegMask;
119123
tmp |= newRegBits;
120124
NRF_GPIOTE->CONFIG[ch] = tmp;
121125
NRF_GPIOTE->INTENSET = (1 << ch); // old code did this ... no harm in ensuring this is set
122-
callbacksInt[ch] = callback;
123-
callbackDeferred[ch] = deferred;
124126
return (1 << ch);
125127
}
126128
}
@@ -133,14 +135,17 @@ int attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode)
133135
if (channelMap[ch] != -1) continue;
134136
// skip if channel is not disabled (e.g., in use by some other component or library)
135137
if (nrf_gpiote_te_is_enabled(NRF_GPIOTE, ch)) continue;
138+
// clear any old events on this GPIOTE channel
139+
NRF_GPIOTE->EVENTS_IN[ch] = 0;
136140
uint32_t tmp = NRF_GPIOTE->CONFIG[ch];
141+
channelMap[ch] = pin;
142+
callbacksInt[ch] = callback;
143+
callbackDeferred[ch] = deferred;
137144
tmp &= oldRegMask;
138145
tmp |= newRegBits;
139146
// TODO: make check/set for new channel an atomic operation
140147
NRF_GPIOTE->CONFIG[ch] = tmp;
141148
NRF_GPIOTE->INTENSET = (1 << ch);
142-
callbacksInt[ch] = callback;
143-
callbackDeferred[ch] = deferred;
144149
return (1 << ch);
145150
}
146151
// Else, pin was neither already setup, nor could a GPIOTE be allocated

0 commit comments

Comments
 (0)