Skip to content

Commit 13fbafb

Browse files
committed
pbio/sys/hmi_pup: Passively monitor connection state.
This way it can run even after the UI completes without needing a separate process. This also simplifies the HMI loop itself, since it won't need to monitor changes. Since BLE advertising is now a no-op when already in the expected state, we can just keep setting it in the waiting loop.
1 parent d1d711f commit 13fbafb

File tree

2 files changed

+39
-70
lines changed

2 files changed

+39
-70
lines changed

lib/pbio/sys/core.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,20 @@ PROCESS_THREAD(pbsys_system_process, ev, data) {
3939
pbsys_program_stop_poll();
4040
pbsys_status_light_poll();
4141

42-
// Revisit: Move to HMI process running parallel to user code.
43-
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_PYBRICKS)) {
44-
pbsys_status_clear(PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED);
45-
}
46-
if (!pbdrv_usb_connection_is_active()) {
42+
// Monitor USB state.
43+
if (pbdrv_usb_connection_is_active()) {
44+
pbsys_status_set(PBIO_PYBRICKS_STATUS_USB_HOST_CONNECTED);
45+
} else {
4746
pbsys_status_clear(PBIO_PYBRICKS_STATUS_USB_HOST_CONNECTED);
4847
}
4948

49+
// Monitor BLE state.
50+
if (pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_PYBRICKS)) {
51+
pbsys_status_set(PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED);
52+
} else {
53+
pbsys_status_clear(PBIO_PYBRICKS_STATUS_BLE_HOST_CONNECTED);
54+
}
55+
5056
// keep the hub from resetting itself
5157
pbdrv_watchdog_update();
5258
}

lib/pbio/sys/hmi_pup.c

Lines changed: 28 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
340306
pbio_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

Comments
 (0)