Skip to content

Commit c4319df

Browse files
authored
Fix GPIO debounce for STM32 (#2781)
***NO_CI***
1 parent 051574f commit c4319df

File tree

1 file changed

+29
-30
lines changed
  • targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio

1 file changed

+29
-30
lines changed

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

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,31 @@
99
#define GPIO_MAX_PIN 256
1010
#define TOTAL_GPIO_PORTS ((GPIO_MAX_PIN + 15) / 16)
1111

12-
// Double linkedlist to hold the state of each Input pin
12+
// Double linked list to hold the state of each Input pin
1313
struct gpio_input_state : public HAL_DblLinkedNode<gpio_input_state>
1414
{
15-
// Pin number
15+
// pin number
1616
GPIO_PIN pinNumber;
17-
// debounce timer for this Pin
17+
// debounce timer for this pin
1818
TX_TIMER debounceTimer;
19-
// Ptr to user ISR or null
19+
// pointer to user ISR or null
2020
GPIO_INTERRUPT_SERVICE_ROUTINE isrPtr;
21-
// debounce Millsecs, no debonce=0
21+
// debounce milliseconds, NO debounce set to 0
2222
uint32_t debounceMs;
2323
// Interrupt mode
2424
uint8_t mode;
25-
// Param to user isr call
25+
// Param to user ISR call
2626
void *param;
2727
// Expected state for debounce handler
2828
bool expected;
2929
// True if waiting for debounce timer to complete
3030
bool waitingDebounce;
3131
};
3232

33-
static HAL_DblLinkedList<gpio_input_state> gpioInputList; // Double Linked list for GPIO input status
34-
static uint16_t pinReserved[TOTAL_GPIO_PORTS]; // reserved - 1 bit per pin
33+
// Double Linked list for GPIO input status
34+
static HAL_DblLinkedList<gpio_input_state> gpioInputList;
35+
// reserved - 1 bit per pin
36+
static uint16_t pinReserved[TOTAL_GPIO_PORTS];
3537

3638
// this is an utility function to get a ChibiOS PAL IoLine from our "encoded" pin number
3739
static ioline_t GetIoLine(int16_t pinNumber)
@@ -52,6 +54,7 @@ bool IsValidGpioPin(GPIO_PIN pinNumber)
5254
gpio_input_state *GetGpioWithInterrupt(uint16_t gpioPin)
5355
{
5456
gpio_input_state *ptr = gpioInputList.FirstNode();
57+
5558
while (ptr->Next() != NULL)
5659
{
5760
if (GPIO_PIN(ptr->pinNumber) == gpioPin)
@@ -65,24 +68,20 @@ gpio_input_state *GetGpioWithInterrupt(uint16_t gpioPin)
6568
return NULL;
6669
}
6770

68-
static void DebounceTimerCallback(uint32_t id)
71+
static void DebounceTimerCallback(ULONG pinState)
6972
{
70-
gpio_input_state *pState = (gpio_input_state *)id;
73+
gpio_input_state *pState = (gpio_input_state *)pinState;
7174

7275
// get current pin state
7376
bool actual = palReadLine(GetIoLine(pState->pinNumber));
7477

7578
if (actual == pState->expected)
7679
{
80+
// call ISR
7781
pState->isrPtr(pState->pinNumber, actual, pState->param);
78-
if (pState->mode == GPIO_INT_EDGE_BOTH)
79-
{
80-
// both edges
81-
// update expected state
82-
pState->expected ^= 1;
83-
}
8482
}
8583

84+
// reset flag
8685
pState->waitingDebounce = false;
8786
}
8887

@@ -96,30 +95,30 @@ void GpioEventCallback(void *arg)
9695

9796
if (pGpio != NULL)
9897
{
99-
// Ignore any pin changes during debounce
100-
if (!pGpio->waitingDebounce)
98+
if (pGpio->waitingDebounce)
99+
{
100+
// Ignore any pin changes during debounce
101+
}
102+
else
101103
{
102104
// check if there is a debounce time set
103105
if (pGpio->debounceMs > 0)
104106
{
107+
// stop timer, just in case
108+
tx_timer_deactivate(&pGpio->debounceTimer);
105109
// Set flag we are waiting for debounce on this pin
106110
pGpio->waitingDebounce = true;
107111

112+
// expecting same state as current one
113+
pGpio->expected = CPU_GPIO_GetPinState(pGpio->pinNumber);
114+
108115
// setup timer
109-
tx_timer_deactivate(&pGpio->debounceTimer);
110-
tx_timer_change(&pGpio->debounceTimer, 0, pGpio->debounceMs / 10);
116+
tx_timer_change(&pGpio->debounceTimer, TX_TICKS_PER_MILLISEC(pGpio->debounceMs), 0);
111117
tx_timer_activate(&pGpio->debounceTimer);
112118
}
113119
else
114120
{
115-
// get IoLine from pin number
116-
ioline_t ioLine = GetIoLine(pGpio->pinNumber);
117-
118-
TX_RESTORE
119-
120-
pGpio->isrPtr(pGpio->pinNumber, palReadLine(ioLine), pGpio->param);
121-
122-
TX_DISABLE
121+
pGpio->isrPtr(pGpio->pinNumber, CPU_GPIO_GetPinState(pGpio->pinNumber), pGpio->param);
123122
}
124123
}
125124
}
@@ -168,9 +167,9 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber)
168167
&ptr->debounceTimer,
169168
(char *)"GPIO debounce timer",
170169
DebounceTimerCallback,
171-
0,
172-
0,
170+
(ULONG)ptr,
173171
1,
172+
0,
174173
TX_NO_ACTIVATE);
175174

176175
gpioInputList.LinkAtBack(ptr);

0 commit comments

Comments
 (0)