@@ -142,36 +142,29 @@ void pbsys_hmi_deinit(void) {
142142 #endif
143143}
144144
145- /**
146- * Tests if the BLE or USB connection has changed.
147- *
148- * @return @c true if the system status is different from the driver status. @c false if unchanged.
149- */
150- static bool host_connection_changed (void ) {
151- return
152- pbdrv_bluetooth_is_connected (PBDRV_BLUETOOTH_CONNECTION_PYBRICKS ) != pbsys_status_test (PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED ) ||
153- pbdrv_usb_connection_is_active () != pbsys_status_test (PBIO_PYBRICKS_STATUS_USB_HOST_CONNECTED );
154- }
155-
156145/**
157146 * The HMI is a loop running the following steps:
158147 *
159- * - Update Bluetooth state, based on current state. This enables or
160- * disables bluetooth and starts/stop advertising.
161148 * - Wait for any buttons to be released in case they were pressed
162- * - Wait for a button press, external program start, or connection change.
163- * - If valid program requested, break out of loop to start program. Otherwise,
164- * update state based on what happened and start over.
149+ * - Wait for a button press, external program start, while monitoring idle
150+ * timeout and BLE advertising.
151+ * - If valid program requested, break out of loop to start program.
152+ * Otherwise, update state based on what happened and start over.
165153 * - After leaving the loop, wait for all buttons to be released.
166154 *
167155 * The three waiting operations are cancelled if poweroff is requested.
168156 */
169- static pbio_error_t run_ui (pbio_os_state_t * state , pbio_os_timer_t * timer ) {
157+ static pbio_error_t run_ui (pbio_os_state_t * state ) {
170158
171159 static pbio_os_state_t sub ;
172160
161+ static pbio_os_timer_t idle_timer ;
162+ static pbio_os_timer_t input_timer ;
163+
173164 PBIO_OS_ASYNC_BEGIN (state );
174165
166+ pbio_os_timer_set (& idle_timer , PBSYS_CONFIG_HMI_IDLE_TIMEOUT_MS );
167+
175168 for (;;) {
176169
177170 DEBUG_PRINT ("Start HMI loop\n" );
@@ -181,37 +174,6 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
181174 light_matrix_show_idle_ui (100 );
182175 #endif
183176
184- // Update USB state.
185- DEBUG_PRINT ("USB Connected: " );
186- if (pbdrv_usb_connection_is_active ()) {
187- DEBUG_PRINT ("Yes.\n" );
188- pbsys_status_set (PBIO_PYBRICKS_STATUS_USB_HOST_CONNECTED );
189- } else {
190- DEBUG_PRINT ("No.\n" );
191- pbsys_status_clear (PBIO_PYBRICKS_STATUS_USB_HOST_CONNECTED );
192- }
193-
194- // Update BLE state.
195- DEBUG_PRINT ("BLE Connected: " );
196- if (pbdrv_bluetooth_is_connected (PBDRV_BLUETOOTH_CONNECTION_PYBRICKS )) {
197- DEBUG_PRINT ("Yes.\n" );
198- pbsys_status_set (PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED );
199- } else {
200- DEBUG_PRINT ("No.\n" );
201- pbsys_status_clear (PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED );
202- }
203-
204- // Advertise if BLE enabled and there is no host connection.
205- bool advertise = pbsys_storage_settings_bluetooth_enabled_get () && !pbsys_host_is_connected ();
206- DEBUG_PRINT ("BLE Advertising: %s. \n" , advertise ? "on" : "off" );
207- if (advertise ) {
208- pbsys_status_set (PBIO_PYBRICKS_STATUS_BLE_ADVERTISING );
209- } else {
210- pbsys_status_clear (PBIO_PYBRICKS_STATUS_BLE_ADVERTISING );
211- }
212- pbdrv_bluetooth_start_advertising (advertise );
213- PBIO_OS_AWAIT (state , & sub , pbdrv_bluetooth_await_advertise_or_scan_command (& sub , NULL ));
214-
215177 // Buttons could be pressed at the end of the user program, so wait for
216178 // a release and then a new press, or until we have to exit early.
217179 DEBUG_PRINT ("Waiting for initial button release.\n" );
@@ -223,9 +185,11 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
223185 }));
224186
225187 DEBUG_PRINT ("Start waiting for input.\n" );
188+
226189 // Wait on a button, external program start, or connection change. Stop
227190 // waiting on timeout or shutdown.
228- PBIO_OS_AWAIT_UNTIL (state , ({
191+ while (!pbdrv_button_get_pressed () && !pbsys_main_program_start_is_requested ()) {
192+
229193 // Shutdown may be requested by a background process such as critical
230194 // battery or holding the power button.
231195 if (pbsys_status_test (PBIO_PYBRICKS_STATUS_SHUTDOWN_REQUEST )) {
@@ -234,21 +198,23 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
234198
235199 // Exit on timeout except while connected to host.
236200 if (pbsys_host_is_connected ()) {
237- pbio_os_timer_set (timer , timer -> duration );
238- } else if (pbio_os_timer_is_expired (timer )) {
201+ pbio_os_timer_set (& idle_timer , idle_timer . duration );
202+ } else if (pbio_os_timer_is_expired (& idle_timer )) {
239203 return PBIO_ERROR_TIMEDOUT ;
240204 }
241205
242- // Wait for button press, external program start, or connection change.
243- pbdrv_button_get_pressed () ||
244- pbsys_main_program_start_is_requested () ||
245- host_connection_changed ();
246- }));
206+ // Advertise if BLE enabled and there is no host connection.
207+ bool advertise = pbsys_storage_settings_bluetooth_enabled_get () && !pbsys_host_is_connected ();
208+ if (advertise ) {
209+ pbsys_status_set (PBIO_PYBRICKS_STATUS_BLE_ADVERTISING );
210+ } else {
211+ pbsys_status_clear (PBIO_PYBRICKS_STATUS_BLE_ADVERTISING );
212+ }
213+ pbdrv_bluetooth_start_advertising (advertise );
214+ PBIO_OS_AWAIT (state , & sub , pbdrv_bluetooth_await_advertise_or_scan_command (& sub , NULL ));
247215
248- // Became connected or disconnected, so go back to handle it.
249- if (host_connection_changed ()) {
250- DEBUG_PRINT ("Connection changed.\n" );
251- continue ;
216+ // Don't block the loop.
217+ PBIO_OS_AWAIT_MS (state , & input_timer , 10 );
252218 }
253219
254220 // External program request takes precedence over buttons.
@@ -261,7 +227,7 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
261227 // Toggle Bluetooth enable setting if Bluetooth button pressed. Only when disconnected.
262228 if ((pbdrv_button_get_pressed () & PBSYS_CONFIG_HMI_PUP_BLUETOOTH_BUTTON ) && !pbsys_host_is_connected ()) {
263229 pbsys_storage_settings_bluetooth_enabled_set (!pbsys_storage_settings_bluetooth_enabled_get ());
264- DEBUG_PRINT ("Toggling Bluetooth to: %s. \n" , pbsys_storage_settings_bluetooth_enabled_get () ? "on" : "off" );
230+ DEBUG_PRINT ("Toggling BLE advertising to: %s. \n" , pbsys_storage_settings_bluetooth_enabled_get () ? "on" : "off" );
265231 continue ;
266232 }
267233 #endif // PBSYS_CONFIG_HMI_PUP_BLUETOOTH_BUTTON
@@ -339,13 +305,10 @@ static pbio_error_t run_ui(pbio_os_state_t *state, pbio_os_timer_t *timer) {
339305 */
340306pbio_error_t pbsys_hmi_await_program_selection (void ) {
341307
342- pbio_os_timer_t idle_timer ;
343- pbio_os_timer_set (& idle_timer , PBSYS_CONFIG_HMI_IDLE_TIMEOUT_MS );
344-
345308 pbio_os_state_t state = 0 ;
346309
347310 pbio_error_t err ;
348- while ((err = run_ui (& state , & idle_timer )) == PBIO_ERROR_AGAIN ) {
311+ while ((err = run_ui (& state )) == PBIO_ERROR_AGAIN ) {
349312 // run all processes and wait for next event.
350313 pbio_os_run_processes_and_wait_for_event ();
351314 }
0 commit comments