Skip to content

Commit

Permalink
drv/button_gpio: add debounce option
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dlech committed Dec 15, 2022
1 parent db29fc1 commit 7933523
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
is still running ([support#849]).
- Fixed Essential hub hanging on boot when bootloader entered but USB cable
not connected ([support#821]).
- Fixed button needs debouncing on City/Technic/Essential hubs ([support#716]).

[support#716]: https://github.com/pybricks/support/issues/716
[support#821]: https://github.com/pybricks/support/issues/821
[support#849]: https://github.com/pybricks/support/issues/849

Expand Down
68 changes: 64 additions & 4 deletions lib/pbio/drv/button/button_gpio.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,96 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2018-2020 The Pybricks Authors
// Copyright (c) 2018-2022 The Pybricks Authors

#include <pbdrv/config.h>

#if PBDRV_CONFIG_BUTTON_GPIO

#include <contiki.h>

#include <pbdrv/gpio.h>
#include <pbio/button.h>
#include <pbio/config.h>
#include <pbio/error.h>

#include "button_gpio.h"

#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE

PROCESS(pbdrv_button_process, "button");

static pbio_button_flags_t pbdrv_button_state;

#endif // PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE

void pbdrv_button_init(void) {
for (int i = 0; i < PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON; i++) {
const pbdrv_button_gpio_platform_t *platform = &pbdrv_button_gpio_platform[i];
pbdrv_gpio_set_pull(&platform->gpio, platform->pull);
pbdrv_gpio_input(&platform->gpio);
}

#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
process_start(&pbdrv_button_process);
#endif
}

pbio_error_t pbdrv_button_is_pressed(pbio_button_flags_t *pressed) {
*pressed = 0;
/**
* Reads the current button state.
* @returns Flags that reflect the current button state.
*/
static pbio_button_flags_t pbdrv_button_gpio_read(void) {
pbio_button_flags_t flags = 0;

for (int i = 0; i < PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON; i++) {
const pbdrv_button_gpio_platform_t *platform = &pbdrv_button_gpio_platform[i];

if (!!pbdrv_gpio_input(&platform->gpio) ^ platform->active_low) {
*pressed |= platform->button;
flags |= platform->button;
}
}

return flags;
}


pbio_error_t pbdrv_button_is_pressed(pbio_button_flags_t *pressed) {
#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE
*pressed = pbdrv_button_state;
#else
*pressed = pbdrv_button_gpio_read();
#endif

return PBIO_SUCCESS;
}

#if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE

PROCESS_THREAD(pbdrv_button_process, ev, data) {
static struct etimer timer;
static pbio_button_flags_t prev, next;

PROCESS_BEGIN();

etimer_set(&timer, 10);

for (;;) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&timer));

next = pbdrv_button_gpio_read();

// when we get the same state twice in a row, consider it "good"
if (next == prev) {
pbdrv_button_state = next;
}

prev = next;

etimer_reset(&timer);
}

PROCESS_END();
}

#endif // PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE

#endif // PBDRV_CONFIG_BUTTON_GPIO
1 change: 1 addition & 0 deletions lib/pbio/platform/city_hub/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define PBDRV_CONFIG_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO (1)
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)

#define PBDRV_CONFIG_BLOCK_DEVICE (1)
#define PBDRV_CONFIG_BLOCK_DEVICE_FLASH_STM32 (1)
Expand Down
1 change: 1 addition & 0 deletions lib/pbio/platform/debug/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define PBDRV_CONFIG_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO (1)
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)

#define PBDRV_CONFIG_CLOCK (1)
#define PBDRV_CONFIG_CLOCK_STM32 (1)
Expand Down
1 change: 1 addition & 0 deletions lib/pbio/platform/essential_hub/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define PBDRV_CONFIG_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO (1)
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)

#define PBDRV_CONFIG_CHARGER (1)
#define PBDRV_CONFIG_CHARGER_MP2639A (1)
Expand Down
1 change: 1 addition & 0 deletions lib/pbio/platform/technic_hub/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define PBDRV_CONFIG_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO (1)
#define PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON (1)
#define PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE (1)

#define PBDRV_CONFIG_CLOCK (1)
#define PBDRV_CONFIG_CLOCK_STM32 (1)
Expand Down

0 comments on commit 7933523

Please sign in to comment.