Skip to content

Commit 3dff7b1

Browse files
committed
sys/bluetooth: keep Bluetooth chip on when not connected
This changes the logic in sys/bluetooth to keep the Bluetooth chip on while a user program is running, even when not connected to a central. This allows the program to initiate a connection to a Bluetooth device like the Powered Up remote control. This also required implementing a new drv/bluetooth function to stop advertising when a user program starts.
1 parent e17e4da commit 3dff7b1

File tree

8 files changed

+78
-5
lines changed

8 files changed

+78
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Added configuration option to run a simplified version of motor PID control.
1313
It is activated on the Move Hub to reduce build size. Motor performance on
1414
the other hubs is unaffected.
15+
- Experimental support for the Powered Up remote control ([support#186]).
1516

1617
### Changed
1718
- Updated MicroPython to v1.16.
@@ -43,6 +44,7 @@ Prerelease changes are documented at [support#48].
4344
[issue#49]: https://github.com/pybricks/pybricks-micropython/issues/49
4445
[support#48]: https://github.com/pybricks/support/issues/48
4546
[support#52]: https://github.com/pybricks/support/issues/52
47+
[support#186]: https://github.com/pybricks/support/issues/186
4648
[support#321]: https://github.com/pybricks/support/issues/321
4749
[support#347]: https://github.com/pybricks/support/issues/347
4850
[support#352]: https://github.com/pybricks/support/issues/352

lib/BlueNRG-MS/hci/controller/bluenrg_gap_aci.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,28 @@ tBleStatus aci_gap_init_end(uint16_t* service_handle, uint16_t* dev_name_char_ha
6666
return 0;
6767
}
6868

69-
tBleStatus aci_gap_set_non_discoverable(void)
69+
tBleStatus aci_gap_set_non_discoverable_begin(void)
7070
{
7171
struct hci_request rq;
72-
uint8_t status;
7372

7473
memset(&rq, 0, sizeof(rq));
7574
rq.opcode = cmd_opcode_pack(OGF_VENDOR_CMD, OCF_GAP_SET_NON_DISCOVERABLE);
75+
76+
hci_send_req(&rq);
77+
78+
return 0;
79+
}
80+
81+
tBleStatus aci_gap_set_non_discoverable_end(void)
82+
{
83+
struct hci_response rq;
84+
uint8_t status;
85+
86+
memset(&rq, 0, sizeof(rq));
7687
rq.rparam = &status;
7788
rq.rlen = 1;
7889

79-
hci_send_req(&rq);
90+
hci_recv_resp(&rq);
8091

8192
return status;
8293
}

lib/BlueNRG-MS/includes/bluenrg_gap_aci.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ tBleStatus aci_gap_init_end(uint16_t* service_handle,
7676
* @note This command will disable the LL advertising.
7777
* @retval tBleStatus Value indicating success or error code.
7878
*/
79-
tBleStatus aci_gap_set_non_discoverable(void);
79+
tBleStatus aci_gap_set_non_discoverable_begin(void);
80+
81+
tBleStatus aci_gap_set_non_discoverable_end(void);
8082

8183
/**
8284
* @brief Put the device in limited discoverable mode

lib/pbio/drv/bluetooth/bluetooth_btstack.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ void pbdrv_bluetooth_start_advertising(void) {
259259
gap_advertisements_enable(true);
260260
}
261261

262+
void pbdrv_bluetooth_stop_advertising(void) {
263+
gap_advertisements_enable(false);
264+
}
265+
262266
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
263267
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && le_con_handle != HCI_CON_HANDLE_INVALID) {
264268
return true;

lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,25 @@ void pbdrv_bluetooth_start_advertising(void) {
238238
pbio_task_start(task_queue, &task);
239239
}
240240

241+
static PT_THREAD(set_non_discoverable(struct pt *pt, pbio_task_t *task)) {
242+
PT_BEGIN(pt);
243+
244+
PT_WAIT_WHILE(pt, write_xfer_size);
245+
aci_gap_set_non_discoverable_begin();
246+
PT_WAIT_UNTIL(pt, hci_command_complete);
247+
aci_gap_set_non_discoverable_end();
248+
249+
task->status = PBIO_SUCCESS;
250+
251+
PT_END(pt);
252+
}
253+
254+
void pbdrv_bluetooth_stop_advertising(void) {
255+
static pbio_task_t task;
256+
pbio_task_init(&task, set_non_discoverable, NULL);
257+
pbio_task_start(task_queue, &task);
258+
}
259+
241260
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
242261
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && conn_handle) {
243262
return true;

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,28 @@ void pbdrv_bluetooth_start_advertising(void) {
289289
pbio_task_start(task_queue, &task);
290290
}
291291

292+
static PT_THREAD(set_non_discoverable(struct pt *pt, pbio_task_t *task)) {
293+
PT_BEGIN(pt);
294+
295+
PT_WAIT_WHILE(pt, write_xfer_size);
296+
GAP_endDiscoverable();
297+
PT_WAIT_UNTIL(pt, hci_command_complete);
298+
// ignoring response data
299+
300+
// REVISIT: technically, this isn't complete until GAP_EndDiscoverableDone
301+
// event is received
302+
303+
task->status = PBIO_SUCCESS;
304+
305+
PT_END(pt);
306+
}
307+
308+
void pbdrv_bluetooth_stop_advertising(void) {
309+
static pbio_task_t task;
310+
pbio_task_init(&task, set_non_discoverable, NULL);
311+
pbio_task_start(task_queue, &task);
312+
}
313+
292314
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
293315
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && conn_handle != NO_CONNECTION) {
294316
return true;

lib/pbio/include/pbdrv/bluetooth.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ bool pbdrv_bluetooth_is_ready(void);
8989
*/
9090
void pbdrv_bluetooth_start_advertising(void);
9191

92+
/**
93+
* Stops the advertising process.
94+
*
95+
* This only needs to be called when no central connects to the hub.
96+
*/
97+
void pbdrv_bluetooth_stop_advertising(void);
98+
9299
/**
93100
* Tests if a central is connected to the Bluetooth chip.
94101
* @param [in] connection The type of connection of interest.

lib/pbio/sys/bluetooth.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ PROCESS_THREAD(pbsys_bluetooth_process, ev, data) {
249249
pbsys_status_set(PBIO_PYBRICKS_STATUS_BLE_ADVERTISING);
250250
PROCESS_WAIT_UNTIL(pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_LE) ||
251251
pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING));
252+
253+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_LE)) {
254+
// if a connection wasn't made, we need to manually stop advertising
255+
pbdrv_bluetooth_stop_advertising();
256+
}
257+
252258
pbsys_status_clear(PBIO_PYBRICKS_STATUS_BLE_ADVERTISING);
253259

254260
PT_INIT(&status_monitor_pt);
@@ -288,11 +294,11 @@ PROCESS_THREAD(pbsys_bluetooth_process, ev, data) {
288294
}
289295

290296
reset_all();
297+
PROCESS_WAIT_WHILE(pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING));
291298

292299
// reset Bluetooth chip
293300
pbdrv_bluetooth_power_on(false);
294301
PROCESS_WAIT_WHILE(pbdrv_bluetooth_is_ready());
295-
PROCESS_WAIT_WHILE(pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING));
296302
}
297303

298304
PROCESS_END();

0 commit comments

Comments
 (0)