From 1a8f0d03090bc73660379372d2dbcd27426e024e Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Wed, 2 Oct 2024 16:02:10 +0200 Subject: [PATCH] pbio/sys/hmi: Run hmi only while user program inactive. The previous approach would go to the start but still run until the next yield. This meant that if the stop button was pressed while a program gracefully exists, it would already be in the "second stage" of the following PT_WAIT_UNTIL(pt, !button_pressed); PT_WAIT_UNTIL(pt, button_pressed); PT_WAIT_UNTIL(pt, !button_pressed); pbsys_main_program_request_start(selected_slot); Then on release, the program would immediately restart. PT_EXIT has the same effect of resetting the state to the start, but existing immediately after that. Fixes https://github.com/pybricks/support/issues/1863 --- lib/pbio/sys/hmi.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/pbio/sys/hmi.c b/lib/pbio/sys/hmi.c index 41b5db23a..fb32a52da 100644 --- a/lib/pbio/sys/hmi.c +++ b/lib/pbio/sys/hmi.c @@ -40,16 +40,15 @@ static uint8_t selected_slot = 0; */ static PT_THREAD(update_program_run_button_wait_state(bool button_pressed)) { struct pt *pt = &update_program_run_button_wait_state_pt; - // Creative use of protothread to reduce code size. This is the same - // as checking if the user program is running after each PT_WAIT. + + // This should not be active while a program is running. if (pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING)) { - goto start; + PT_EXIT(pt); } PT_BEGIN(pt); for (;;) { - start: // button may still be pressed from power on or user program stop PT_WAIT_UNTIL(pt, !button_pressed); PT_WAIT_UNTIL(pt, button_pressed); @@ -73,16 +72,15 @@ static struct pt update_bluetooth_button_wait_state_pt; */ static PT_THREAD(update_bluetooth_button_wait_state(bool button_pressed)) { struct pt *pt = &update_bluetooth_button_wait_state_pt; - // Creative use of protothread to reduce code size. This is the same - // as checking if the user program is running after each PT_WAIT. + + // This should not be active while a program is running. if (pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING)) { - goto start; + PT_EXIT(pt); } PT_BEGIN(pt); for (;;) { - start: // button may still be pressed during user program PT_WAIT_UNTIL(pt, !button_pressed); PT_WAIT_UNTIL(pt, button_pressed); @@ -115,10 +113,10 @@ uint8_t pbsys_hmi_get_selected_program_slot(void) { */ static PT_THREAD(update_left_right_button_wait_state(bool left_button_pressed, bool right_button_pressed)) { struct pt *pt = &update_left_right_button_wait_state_pt; - // Creative use of protothread to reduce code size. This is the same - // as checking if the user program is running after each PT_WAIT. + + // This should not be active while a program is running. if (pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING)) { - goto start; + PT_EXIT(pt); } static uint8_t previous_slot; @@ -127,7 +125,6 @@ static PT_THREAD(update_left_right_button_wait_state(bool left_button_pressed, b PT_BEGIN(pt); for (;;) { - start: // Buttons may still be pressed during user program PT_WAIT_UNTIL(pt, !left_button_pressed && !right_button_pressed);