Skip to content

Commit cc17635

Browse files
authored
Fix GPIO events (#3234)
1 parent 5ee2558 commit cc17635

File tree

6 files changed

+82
-29
lines changed

6 files changed

+82
-29
lines changed

targets/AzureRTOS/Maxim/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct gpio_input_state : public HAL_DblLinkedNode<gpio_input_state>
3838
void *param;
3939
// Expected state for debounce handler
4040
GPIO_PinState expected;
41+
// Current pin state
42+
GPIO_PinState current;
4143
// True if waiting for debounce timer to complete
4244
bool waitingDebounce;
4345
};
@@ -76,14 +78,15 @@ static void DebounceTimerCallback(uint32_t id)
7678
// get current pin state
7779
bool actual = HAL_GPIO_ReadPin(port, GPIO_PIN(pState->pinNumber));
7880

79-
if (actual == pState->expected)
81+
if (actual == pState->current)
8082
{
8183
pState->isrPtr(pState->pinNumber, actual, pState->param);
84+
8285
if (pState->mode == GPIO_INT_EDGE_BOTH)
8386
{
8487
// both edges
85-
// update expected state
86-
pState->expected = (GPIO_PinState)(pState->expected ^ GPIO_PIN_SET);
88+
// update current state
89+
pState->current = (GPIO_PinState)(pState->current ^ GPIO_PIN_SET);
8790
}
8891
}
8992

@@ -123,10 +126,14 @@ void HAL_GPIO_EXTI_Callback(uint16_t gpioPin)
123126
{
124127
TX_RESTORE
125128

126-
pGpio->isrPtr(
127-
pGpio->pinNumber,
128-
HAL_GPIO_ReadPin(GPIO_PORT(pGpio->pinNumber), GPIO_PIN(pGpio->pinNumber)),
129-
pGpio->param);
129+
bool level = HAL_GPIO_ReadPin(GPIO_PORT(pGpio->pinNumber), GPIO_PIN(pGpio->pinNumber));
130+
131+
if (level != pGpio->current)
132+
{
133+
pGpio->current = level;
134+
135+
pGpio->isrPtr(pGpio->pinNumber, level, pGpio->param);
136+
}
130137

131138
TX_DISABLE
132139
}
@@ -167,6 +174,7 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber)
167174
{
168175
memset(ptr, 0, sizeof(gpio_input_state));
169176
ptr->pinNumber = pinNumber;
177+
ptr->current = HAL_GPIO_ReadPin(GPIO_PORT(pGpio->pinNumber), GPIO_PIN(pGpio->pinNumber));
170178

171179
tx_timer_create(
172180
&ptr->debounceTimer,
@@ -490,7 +498,7 @@ void CPU_GPIO_DisablePin(GPIO_PIN pinNumber, GpioPinDriveMode driveMode, uint32_
490498

491499
GPIO_TypeDef *port = GPIO_PORT(pinNumber);
492500
uint32_t pin = GPIO_PIN(pinNumber);
493-
501+
494502
GPIO_InitTypeDef gpio_init_structure;
495503
gpio_init_structure.Pin = pin;
496504

targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ static void DebounceTimerCallback(ULONG pinState)
7979
{
8080
// call ISR
8181
pState->isrPtr(pState->pinNumber, actual, pState->param);
82+
83+
if (pState->mode == GPIO_INT_EDGE_BOTH)
84+
{
85+
// update expected state
86+
pState->expected ^= 1;
87+
}
8288
}
8389

8490
// reset flag

targets/ChibiOS/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct gpio_input_state : public HAL_DblLinkedNode<gpio_input_state>
2323
uint8_t mode; // Interrupt mode
2424
void *param; // Param to user isr call
2525
bool expected; // Expected state for debounce handler
26+
bool current; // Current pin state
2627
bool waitingDebounce; // True if waiting for debounce timer to complete
2728
};
2829

@@ -53,10 +54,11 @@ static void DebounceTimerCallback(virtual_timer_t *vtp, void *arg)
5354
if (actual == pState->expected)
5455
{
5556
pState->isrPtr(pState->pinNumber, actual, pState->param);
57+
5658
if (pState->mode == GPIO_INT_EDGE_BOTH)
5759
{
58-
// both edges
59-
pState->expected ^= 1; // update expected state
60+
// update expected state
61+
pState->expected ^= 1;
6062
}
6163
}
6264

@@ -92,9 +94,14 @@ static void GpioEventCallback(void *arg)
9294
// get IoLine from pin number
9395
ioline_t ioLine = GetIoLine(pGpio->pinNumber);
9496

95-
chSysUnlockFromISR();
96-
pGpio->isrPtr(pGpio->pinNumber, palReadLine(ioLine), pGpio->param);
97-
chSysLockFromISR();
97+
bool level = palReadLine(ioLine);
98+
99+
if (level != pGpio->current)
100+
{
101+
pGpio->current = level;
102+
103+
pGpio->isrPtr(pGpio->pinNumber, level, pGpio->param);
104+
}
98105
}
99106

100107
chSysUnlockFromISR();
@@ -131,6 +138,7 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber)
131138
{
132139
memset(ptr, 0, sizeof(gpio_input_state));
133140
ptr->pinNumber = pinNumber;
141+
ptr->current = palReadLine(GetIoLine(pinNumber));
134142

135143
chVTObjectInit(&ptr->debounceTimer);
136144

targets/ESP32/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ static void Esp_Gpio_DebounceHandler(TimerHandle_t timer)
141141
if (state != NULL)
142142
{
143143
// get current pin state
144-
bool actual = CPU_GPIO_GetPinState(state->pinNumber);
144+
GpioPinValue actual = CPU_GPIO_GetPinState(state->pinNumber);
145145

146146
if (actual == state->expected)
147147
{
@@ -317,9 +317,6 @@ static void gpio_isr(void *arg)
317317
return;
318318
}
319319

320-
// get current pin state
321-
bool actual = CPU_GPIO_GetPinState(state->pinNumber);
322-
323320
if (state->debounceMs > 0)
324321
{
325322
// flag waiting for debounce timeout
@@ -338,9 +335,15 @@ static void gpio_isr(void *arg)
338335
}
339336
else
340337
{
341-
state->current = actual;
342-
// just fire event
343-
state->isrPtr(state->pinNumber, actual, state->param);
338+
// get current pin state
339+
GpioPinValue actual = gpio_get_level((gpio_num_t)state->pinNumber) ? GpioPinValue_High : GpioPinValue_Low;
340+
341+
if (actual != state->current)
342+
{
343+
state->current = actual;
344+
345+
state->isrPtr(state->pinNumber, actual, state->param);
346+
}
344347
}
345348

346349
NATIVE_INTERRUPT_END
@@ -361,6 +364,8 @@ bool CPU_GPIO_EnableInputPin(
361364
if (driveMode >= (int)PinMode_Output)
362365
return false;
363366

367+
gpio_reset_pin((gpio_num_t)pinNumber);
368+
364369
// Set as Input GPIO_INT_EDGE intEdge, GPIO_RESISTOR ResistorState
365370
if (!CPU_GPIO_SetDriveMode(pinNumber, driveMode))
366371
{
@@ -456,6 +461,8 @@ bool CPU_GPIO_EnableOutputPin(GPIO_PIN pinNumber, GpioPinValue InitialState, Pin
456461
// If this is currently an input pin then clean up
457462
DeleteInputState(pinNumber);
458463

464+
gpio_reset_pin((gpio_num_t)pinNumber);
465+
459466
if (CPU_GPIO_SetDriveMode(pinNumber, driveMode) == false)
460467
{
461468
return false;

targets/FreeRTOS/NXP/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct gpio_input_state
2828
uint8_t mode; // Interrupt mode
2929
void *param; // Param to user isr call
3030
bool expected; // Expected state for debounce handler
31+
bool current; // Current pin state
3132
bool waitingDebounce; // True if waiting for debounce timer to complete
3233
};
3334

@@ -60,8 +61,9 @@ void Gpio_DebounceHandler(TimerHandle_t xTimer)
6061
pState->isrPtr(pState->pinNumber, actual, pState->param);
6162

6263
if (pState->mode == GPIO_INT_EDGE_BOTH)
63-
{ // both edges
64-
pState->expected ^= 1; // update expected state
64+
{
65+
// update expected state
66+
pState->expected ^= 1;
6567
}
6668
}
6769

@@ -121,13 +123,19 @@ void GPIO_Main_IRQHandler(int portIndex, GPIO_Type *portBase)
121123
}
122124
else
123125
{
124-
GpioPinValue PinState =
125-
(GpioPinValue)GPIO_PinRead(GPIO_BASE(pState->pinNumber), GPIO_PIN(pState->pinNumber));
126-
pState->isrPtr(pState->pinNumber, PinState, pState->param);
126+
bool pinState =
127+
GPIO_PinRead(GPIO_BASE(pState->pinNumber), GPIO_PIN(pState->pinNumber)) != 0;
128+
129+
if (pinState != pState->current)
130+
{
131+
pState->current = pinState;
132+
133+
pState->isrPtr(pState->pinNumber, pinState, pState->param);
134+
}
127135
}
128136
}
129137
} // if pin setup in nanoFramework
130-
} // if interrupt
138+
} // if interrupt
131139

132140
intPins >>= 1;
133141
bitNumber++;
@@ -237,6 +245,7 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber)
237245
pState = (gpio_input_state *)platform_malloc(sizeof(gpio_input_state));
238246
memset(pState, 0, sizeof(gpio_input_state));
239247
pState->pinNumber = pinNumber;
248+
pState->current = GPIO_PinRead(GPIO_BASE(pinNumber), GPIO_PIN(pinNumber));
240249
(*inputStates)[bit] = pState;
241250
}
242251
return pState;

targets/TI_SimpleLink/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ struct gpio_input_state : public HAL_DblLinkedNode<gpio_input_state>
4949
// expected state for debounce handler
5050
uint_fast8_t expected;
5151

52+
// current pin state
53+
uint_fast8_t current;
54+
5255
// flag for waiting for debounce timer to complete
5356
bool waitingDebounce;
5457
};
@@ -117,6 +120,8 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber)
117120
// store the pin number
118121
pState->pinNumber = pinNumber;
119122

123+
pState->current = GPIO_read(pinNumber);
124+
120125
gpioInputList.LinkAtBack(pState);
121126
}
122127
}
@@ -174,8 +179,13 @@ static void DebounceTimerCallback(UArg arg)
174179

175180
if (pinState == pState->expected)
176181
{
177-
// post a managed event with the current pin reading
178182
pState->isrPtr(pState->pinNumber, pinState, pState->param);
183+
184+
if (pState->mode == GPIO_INT_EDGE_BOTH)
185+
{
186+
// update expected state
187+
pState->expected ^= 1;
188+
}
179189
}
180190

181191
pState->waitingDebounce = false;
@@ -215,8 +225,12 @@ static void GpioEventCallback(uint_least8_t index)
215225
}
216226
else
217227
{
218-
// No debounce so just post a managed event with the current pin reading
219-
pState->isrPtr(pState->pinNumber, pinState, pState->param);
228+
if (pinState != pState->current)
229+
{
230+
pState->current = pinState;
231+
232+
pState->isrPtr(pState->pinNumber, pinState, pState->param);
233+
}
220234
}
221235
}
222236
}
@@ -368,6 +382,7 @@ bool CPU_GPIO_EnableInputPin(
368382
pState->mode = intEdge;
369383
pState->param = isrParam;
370384
pState->debounceMs = debounceTimeMilliseconds;
385+
pState->current = CPU_GPIO_GetPinState(pState->pinConfigIndex);
371386

372387
// create timer if not there yet
373388
if (pState->debounceMs > 0 && pState->debounceTimer == NULL)

0 commit comments

Comments
 (0)