From b45b2722d842c9ae4c2f7800a3b767bfd82bd4b9 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 6 Oct 2025 14:11:47 +0200 Subject: [PATCH] pbio/drv/button_gpio: Wait for release and delay on power down. Fixes https://github.com/pybricks/support/issues/2176 --- lib/pbio/drv/button/button.h | 6 ++++++ lib/pbio/drv/button/button_gpio.c | 19 ++++++++++++++++--- lib/pbio/drv/button/button_nxt.c | 3 +++ lib/pbio/drv/button/button_resistor_ladder.c | 3 +++ lib/pbio/drv/button/button_test.c | 3 +++ lib/pbio/drv/core.c | 1 + 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/pbio/drv/button/button.h b/lib/pbio/drv/button/button.h index cbdea165b..1b11a4045 100644 --- a/lib/pbio/drv/button/button.h +++ b/lib/pbio/drv/button/button.h @@ -15,9 +15,15 @@ */ void pbdrv_button_init(void); +/** + * De-initializes the low level button driver. + */ +void pbdrv_button_deinit(void); + #else #define pbdrv_button_init() +#define pbdrv_button_deinit() #endif diff --git a/lib/pbio/drv/button/button_gpio.c b/lib/pbio/drv/button/button_gpio.c index 3df64a93a..4248dfabd 100644 --- a/lib/pbio/drv/button/button_gpio.c +++ b/lib/pbio/drv/button/button_gpio.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -49,7 +50,9 @@ pbio_error_t pbdrv_button_process_thread(pbio_os_state_t *state, void *context) pbio_os_timer_set(&timer, 10); - for (;;) { + // Loop until cancellation is requested on power off and buttons are released. + while (!pbdrv_button_process.request || pbdrv_button_state) { + PBIO_OS_AWAIT_UNTIL(state, pbio_os_timer_is_expired(&timer)); next = pbdrv_button_gpio_read(); @@ -64,8 +67,11 @@ pbio_error_t pbdrv_button_process_thread(pbio_os_state_t *state, void *context) pbio_os_timer_extend(&timer); } - // Unreachable - PBIO_OS_ASYNC_END(PBIO_ERROR_FAILED); + // Wait a while after release to prevent accidental power on. + PBIO_OS_AWAIT_MS(state, &timer, 200); + pbio_busy_count_down(); + + PBIO_OS_ASYNC_END(PBIO_ERROR_CANCELED); } #endif // PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE @@ -90,4 +96,11 @@ void pbdrv_button_init(void) { #endif } +void pbdrv_button_deinit(void) { + #if PBDRV_CONFIG_BUTTON_GPIO_DEBOUNCE + pbio_busy_count_up(); + pbio_os_process_make_request(&pbdrv_button_process, PBIO_OS_PROCESS_REQUEST_TYPE_CANCEL); + #endif +} + #endif // PBDRV_CONFIG_BUTTON_GPIO diff --git a/lib/pbio/drv/button/button_nxt.c b/lib/pbio/drv/button/button_nxt.c index ccad088f1..bb16f5c68 100644 --- a/lib/pbio/drv/button/button_nxt.c +++ b/lib/pbio/drv/button/button_nxt.c @@ -14,6 +14,9 @@ void pbdrv_button_init(void) { } +void pbdrv_button_deinit(void) { +} + pbio_button_flags_t pbdrv_button_get_pressed(void) { nx_avr_button_t button = nx_avr_get_button(); diff --git a/lib/pbio/drv/button/button_resistor_ladder.c b/lib/pbio/drv/button/button_resistor_ladder.c index cc7e00b3f..8c09d62d7 100644 --- a/lib/pbio/drv/button/button_resistor_ladder.c +++ b/lib/pbio/drv/button/button_resistor_ladder.c @@ -48,6 +48,9 @@ void pbdrv_button_init(void) { pbio_os_process_start(&pbdrv_button_init_process, pbdrv_button_init_process_thread, NULL); } +void pbdrv_button_deinit(void) { +} + pbio_button_flags_t pbdrv_button_get_pressed(void) { pbdrv_resistor_ladder_ch_flags_t flags; pbio_error_t err; diff --git a/lib/pbio/drv/button/button_test.c b/lib/pbio/drv/button/button_test.c index b365a6848..d82d1c118 100644 --- a/lib/pbio/drv/button/button_test.c +++ b/lib/pbio/drv/button/button_test.c @@ -19,6 +19,9 @@ void pbio_test_button_set_pressed(pbio_button_flags_t flags) { void pbdrv_button_init(void) { } +void pbdrv_button_deinit(void) { +} + pbio_button_flags_t pbdrv_button_get_pressed(void) { return pbio_test_button_flags; } diff --git a/lib/pbio/drv/core.c b/lib/pbio/drv/core.c index 4017fc93c..b485ac0c9 100644 --- a/lib/pbio/drv/core.c +++ b/lib/pbio/drv/core.c @@ -89,6 +89,7 @@ void pbdrv_deinit(void) { pbdrv_imu_deinit(); pbdrv_bluetooth_deinit(); + pbdrv_button_deinit(); while (pbio_busy_count_busy()) { pbio_os_run_processes_and_wait_for_event();