|
8 | 8 |
|
9 | 9 | #include <stdbool.h> |
10 | 10 |
|
| 11 | +#include <pbdrv/bluetooth.h> |
| 12 | +#include <pbdrv/display.h> |
11 | 13 | #include <pbdrv/sound.h> |
12 | 14 |
|
13 | 15 | #include <pbio/battery.h> |
| 16 | +#include <pbio/image.h> |
14 | 17 | #include <pbio/imu.h> |
15 | 18 | #include <pbio/motor_process.h> |
16 | 19 | #include <pbio/port_interface.h> |
@@ -51,26 +54,62 @@ void pbio_deinit(void) { |
51 | 54 | } |
52 | 55 |
|
53 | 56 | /** |
54 | | - * Stops all user-level background processes. Called when the user application |
55 | | - * completes to get these modules back into their default state. Drivers and |
56 | | - * OS-level processes continue running. |
| 57 | + * Stops resources like motors or sounds or peripheral procedures that take a |
| 58 | + * long time. |
57 | 59 | * |
58 | | - * @param [in] reset Whether to reset all user-level processes to a clean |
59 | | - * state (true), or whether to only stop active outputs |
60 | | - * like sound or motors (false). The latter is useful to |
61 | | - * preserve the state for debugging, without sound or |
62 | | - * movement getting in the way, or out of control. |
| 60 | + * Useful to get the system in a safe state for the user without doing a full |
| 61 | + * reset. Applications can all this to enter a user debug mode like the |
| 62 | + * MicroPython REPL. |
63 | 63 | */ |
64 | | -void pbio_stop_all(bool reset) { |
65 | | - #if PBIO_CONFIG_LIGHT |
66 | | - if (reset) { |
67 | | - pbio_light_animation_stop_all(); |
68 | | - } |
69 | | - #endif |
| 64 | +void pbio_main_soft_stop(void) { |
70 | 65 |
|
71 | | - pbio_port_stop_user_actions(reset); |
| 66 | + pbio_port_stop_user_actions(false); |
72 | 67 |
|
73 | 68 | pbdrv_sound_stop(); |
| 69 | + |
| 70 | + pbdrv_bluetooth_cancel_operation_request(); |
| 71 | +} |
| 72 | + |
| 73 | +static void wait_for_bluetooth(void) { |
| 74 | + pbio_os_state_t unused; |
| 75 | + while (pbdrv_bluetooth_await_advertise_or_scan_command(&unused, NULL) == PBIO_ERROR_AGAIN || |
| 76 | + pbdrv_bluetooth_await_peripheral_command(&unused, NULL) == PBIO_ERROR_AGAIN) { |
| 77 | + |
| 78 | + // Run event loop until Bluetooth is idle. |
| 79 | + pbio_os_run_processes_and_wait_for_event(); |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +/** |
| 84 | + * Stops all application-level background processes. Called when the user |
| 85 | + * application completes to get these modules back into their default state. |
| 86 | + * Drivers and OS-level processes continue running. |
| 87 | + */ |
| 88 | +void pbio_main_stop_application_resources() { |
| 89 | + |
| 90 | + pbio_main_soft_stop(); |
| 91 | + |
| 92 | + // Let ongoing task finish first. |
| 93 | + wait_for_bluetooth(); |
| 94 | + |
| 95 | + // Stop broadcasting, observing and disconnect peripheral. |
| 96 | + pbdrv_bluetooth_start_broadcasting(NULL, 0); |
| 97 | + wait_for_bluetooth(); |
| 98 | + |
| 99 | + pbdrv_bluetooth_start_observing(NULL); |
| 100 | + wait_for_bluetooth(); |
| 101 | + |
| 102 | + pbdrv_bluetooth_peripheral_disconnect(); |
| 103 | + wait_for_bluetooth(); |
| 104 | + |
| 105 | + #if PBIO_CONFIG_LIGHT |
| 106 | + pbio_light_animation_stop_all(); |
| 107 | + #endif |
| 108 | + |
| 109 | + #if PBDRV_CONFIG_DISPLAY |
| 110 | + pbio_image_fill(pbdrv_display_get_image(), 0); |
| 111 | + pbdrv_display_update(); |
| 112 | + #endif |
74 | 113 | } |
75 | 114 |
|
76 | 115 | /** @} */ |
0 commit comments