Skip to content

Commit 7933523

Browse files
committed
drv/button_gpio: add debounce option
This adds an option to enable debouncing gpio buttons to the gpio button driver. Some hubs have exhibited a need for debouncing. Fixes: pybricks/support#716
1 parent db29fc1 commit 7933523

File tree

6 files changed

+70
-4
lines changed

6 files changed

+70
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
is still running ([support#849]).
1010
- Fixed Essential hub hanging on boot when bootloader entered but USB cable
1111
not connected ([support#821]).
12+
- Fixed button needs debouncing on City/Technic/Essential hubs ([support#716]).
1213

14+
[support#716]: https://github.com/pybricks/support/issues/716
1315
[support#821]: https://github.com/pybricks/support/issues/821
1416
[support#849]: https://github.com/pybricks/support/issues/849
1517

lib/pbio/drv/button/button_gpio.c

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,96 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2018-2020 The Pybricks Authors
2+
// Copyright (c) 2018-2022 The Pybricks Authors
33

44
#include <pbdrv/config.h>
55

66
#if PBDRV_CONFIG_BUTTON_GPIO
77

8+
#include <contiki.h>
9+
810
#include <pbdrv/gpio.h>
911
#include <pbio/button.h>
1012
#include <pbio/config.h>
1113
#include <pbio/error.h>
1214

1315
#include "button_gpio.h"
1416

17+
#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
18+
19+
PROCESS(pbdrv_button_process, "button");
20+
21+
static pbio_button_flags_t pbdrv_button_state;
22+
23+
#endif // PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
24+
1525
void pbdrv_button_init(void) {
1626
for (int i = 0; i < PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON; i++) {
1727
const pbdrv_button_gpio_platform_t *platform = &pbdrv_button_gpio_platform[i];
1828
pbdrv_gpio_set_pull(&platform->gpio, platform->pull);
1929
pbdrv_gpio_input(&platform->gpio);
2030
}
31+
32+
#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
33+
process_start(&pbdrv_button_process);
34+
#endif
2135
}
2236

23-
pbio_error_t pbdrv_button_is_pressed(pbio_button_flags_t *pressed) {
24-
*pressed = 0;
37+
/**
38+
* Reads the current button state.
39+
* @returns Flags that reflect the current button state.
40+
*/
41+
static pbio_button_flags_t pbdrv_button_gpio_read(void) {
42+
pbio_button_flags_t flags = 0;
2543

2644
for (int i = 0; i < PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON; i++) {
2745
const pbdrv_button_gpio_platform_t *platform = &pbdrv_button_gpio_platform[i];
46+
2847
if (!!pbdrv_gpio_input(&platform->gpio) ^ platform->active_low) {
29-
*pressed |= platform->button;
48+
flags |= platform->button;
3049
}
3150
}
3251

52+
return flags;
53+
}
54+
55+
56+
pbio_error_t pbdrv_button_is_pressed(pbio_button_flags_t *pressed) {
57+
#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
58+
*pressed = pbdrv_button_state;
59+
#else
60+
*pressed = pbdrv_button_gpio_read();
61+
#endif
62+
3363
return PBIO_SUCCESS;
3464
}
3565

66+
#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
67+
68+
PROCESS_THREAD(pbdrv_button_process, ev, data) {
69+
static struct etimer timer;
70+
static pbio_button_flags_t prev, next;
71+
72+
PROCESS_BEGIN();
73+
74+
etimer_set(&timer, 10);
75+
76+
for (;;) {
77+
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&timer));
78+
79+
next = pbdrv_button_gpio_read();
80+
81+
// when we get the same state twice in a row, consider it "good"
82+
if (next == prev) {
83+
pbdrv_button_state = next;
84+
}
85+
86+
prev = next;
87+
88+
etimer_reset(&timer);
89+
}
90+
91+
PROCESS_END();
92+
}
93+
94+
#endif // PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
95+
3696
#endif // PBDRV_CONFIG_BUTTON_GPIO

lib/pbio/platform/city_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define PBDRV_CONFIG_BUTTON (1)
2222
#define PBDRV_CONFIG_BUTTON_GPIO (1)
2323
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
24+
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)
2425

2526
#define PBDRV_CONFIG_BLOCK_DEVICE (1)
2627
#define PBDRV_CONFIG_BLOCK_DEVICE_FLASH_STM32 (1)

lib/pbio/platform/debug/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define PBDRV_CONFIG_BUTTON (1)
1515
#define PBDRV_CONFIG_BUTTON_GPIO (1)
1616
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
17+
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)
1718

1819
#define PBDRV_CONFIG_CLOCK (1)
1920
#define PBDRV_CONFIG_CLOCK_STM32 (1)

lib/pbio/platform/essential_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#define PBDRV_CONFIG_BUTTON (1)
4646
#define PBDRV_CONFIG_BUTTON_GPIO (1)
4747
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
48+
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)
4849

4950
#define PBDRV_CONFIG_CHARGER (1)
5051
#define PBDRV_CONFIG_CHARGER_MP2639A (1)

lib/pbio/platform/technic_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define PBDRV_CONFIG_BUTTON (1)
3535
#define PBDRV_CONFIG_BUTTON_GPIO (1)
3636
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
37+
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)
3738

3839
#define PBDRV_CONFIG_CLOCK (1)
3940
#define PBDRV_CONFIG_CLOCK_STM32 (1)

0 commit comments

Comments
 (0)