1111
1212#include <pbdrv/bluetooth.h>
1313
14+ #include <pbio/busy_count.h>
1415#include <pbio/error.h>
1516#include <pbio/os.h>
1617#include <pbio/protocol.h>
@@ -411,6 +412,8 @@ pbio_error_t pbdrv_bluetooth_await_advertise_or_scan_command(pbio_os_state_t *st
411412 return advertising_or_scan_func ? advertising_or_scan_err : PBIO_SUCCESS ;
412413}
413414
415+ static bool shutting_down ;
416+
414417/**
415418 * This is the main high level pbdrv/bluetooth thread. It is driven forward by
416419 * the platform-specific HCI process whenever there is new data to process or
@@ -434,7 +437,9 @@ pbio_error_t pbdrv_bluetooth_process_thread(pbio_os_state_t *state, void *contex
434437
435438 PBIO_OS_ASYNC_BEGIN (state );
436439
437- for (;;) {
440+ while (!shutting_down ) {
441+
442+ DEBUG_PRINT ("Bluetooth disable requested.\n" );
438443
439444 pbdrv_bluetooth_is_broadcasting = false;
440445 pbdrv_bluetooth_is_observing = false;
@@ -447,7 +452,10 @@ pbio_error_t pbdrv_bluetooth_process_thread(pbio_os_state_t *state, void *contex
447452 pbio_os_request_poll ();
448453
449454 // Bluetooth is now disabled. Await system processes to ask for enable.
450- PBIO_OS_AWAIT_UNTIL (state , power_on_requested );
455+ PBIO_OS_AWAIT_UNTIL (state , power_on_requested || shutting_down );
456+ if (shutting_down ) {
457+ break ;
458+ }
451459 DEBUG_PRINT ("Bluetooth enable requested.\n" );
452460
453461 PBIO_OS_AWAIT (state , & sub , err = pbdrv_bluetooth_controller_initialize (& sub , & timer ));
@@ -463,9 +471,11 @@ pbio_error_t pbdrv_bluetooth_process_thread(pbio_os_state_t *state, void *contex
463471 pbio_os_timer_set (& status_timer , PBDRV_BLUETOOTH_STATUS_UPDATE_INTERVAL );
464472
465473 // Service scheduled tasks as long as Bluetooth is enabled.
466- while (power_on_requested ) {
474+ while (power_on_requested && ! shutting_down ) {
467475
468- // REVISIT: Only needed if there is nothing to do
476+ // In principle, this wait is only needed if there is nothing to do.
477+ // In practice, leaving it here helps rather than hurts since it
478+ // allows short stdout messages to be queued rather than sent separately.
469479 PBIO_OS_AWAIT_MS (state , & timer , 1 );
470480
471481 // Handle pending status update, if any.
@@ -534,11 +544,26 @@ pbio_error_t pbdrv_bluetooth_process_thread(pbio_os_state_t *state, void *contex
534544 observe_restart_requested = false;
535545 }
536546 }
537-
538- DEBUG_PRINT ("Bluetooth disable requested.\n" );
539547 }
540548
549+ DEBUG_PRINT ("Shutdown requested.\n" );
550+
551+ // Power down the chip. This will disconnect from the host first.
552+ // The peripheral has already been disconnected in the cleanup that runs after
553+ // every program. If we change that behavior, we can do the disconnect here.
554+
555+ PBIO_OS_AWAIT (state , & sub , pbdrv_bluetooth_controller_reset (& sub , & timer ));
556+
557+ pbio_busy_count_down ();
558+
541559 PBIO_OS_ASYNC_END (PBIO_SUCCESS );
542560}
543561
562+ void pbdrv_bluetooth_deinit (void ) {
563+ pbio_busy_count_up ();
564+ pbdrv_bluetooth_cancel_operation_request ();
565+ shutting_down = true;
566+ pbio_os_request_poll ();
567+ }
568+
544569#endif // PBDRV_CONFIG_BLUETOOTH_STM32_CC2640
0 commit comments