Skip to content

Commit df2fbca

Browse files
committed
pbio/drv/bluetooth_stm32_cc2640: Only restart observe when needed.
Everytime we restart observing, there is a small chance of locking up the Bluetooth chip. The restart was added as a workaround for the scan queue getting full so new scan events were not coming in. This usually doesn't happen for a long time, so we can avoid restarting observing until then. Since there isn't a good way to know if the queue is full, we can request a restart if we are not receiving data when the user is expecting some data. In the worst case, this will still restart it every 10 seconds as it used to do. If all of the subscribed channels get incoming data, restarting is delayed, thus reducing the likelihood of a freeze.
1 parent 3198a85 commit df2fbca

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ static const pbdrv_bluetooth_stm32_cc2640_platform_data_t *pdata = &pbdrv_blueto
160160
#define SCAN_RESTART_INTERVAL 3000
161161
#define OBSERVE_RESTART_INTERVAL 10000
162162
static struct etimer scan_restart_timer;
163-
static struct etimer observe_restart_timer;
164-
static bool observe_restart_enabled;
163+
static bool observe_restart_requested;
164+
static uint32_t observe_restart_time;
165165

166166
/**
167167
* Converts a ble error code to the most appropriate pbio error code.
@@ -500,7 +500,6 @@ static PT_THREAD(peripheral_scan_and_connect_task(struct pt *pt, pbio_task_t *ta
500500

501501
// temporarily stop observing so we can active scan
502502
if (is_observing) {
503-
observe_restart_enabled = false;
504503

505504
PT_WAIT_WHILE(pt, write_xfer_size);
506505
GAP_DeviceDiscoveryCancel();
@@ -747,10 +746,8 @@ static PT_THREAD(peripheral_scan_and_connect_task(struct pt *pt, pbio_task_t *ta
747746

748747
device_discovery_done = false;
749748

750-
PROCESS_CONTEXT_BEGIN(&pbdrv_bluetooth_spi_process);
751-
etimer_set(&observe_restart_timer, OBSERVE_RESTART_INTERVAL);
752-
PROCESS_CONTEXT_END(&pbdrv_bluetooth_spi_process);
753-
observe_restart_enabled = true;
749+
observe_restart_time = pbdrv_clock_get_ms();
750+
observe_restart_requested = false;
754751
}
755752

756753
PT_END(pt);
@@ -1162,10 +1159,8 @@ static PT_THREAD(observe_task(struct pt *pt, pbio_task_t *task)) {
11621159
device_discovery_done = false;
11631160
is_observing = true;
11641161

1165-
PROCESS_CONTEXT_BEGIN(&pbdrv_bluetooth_spi_process);
1166-
etimer_set(&observe_restart_timer, OBSERVE_RESTART_INTERVAL);
1167-
PROCESS_CONTEXT_END(&pbdrv_bluetooth_spi_process);
1168-
observe_restart_enabled = true;
1162+
observe_restart_time = pbdrv_clock_get_ms();
1163+
observe_restart_requested = false;
11691164
}
11701165

11711166
task->status = PBIO_SUCCESS;
@@ -1201,11 +1196,16 @@ static PT_THREAD(stop_observe_task(struct pt *pt, pbio_task_t *task)) {
12011196
void pbdrv_bluetooth_stop_observing(pbio_task_t *task) {
12021197
observe_callback = NULL;
12031198
// avoid restarting observing even if this task get queued
1204-
observe_restart_enabled = false;
1199+
observe_restart_requested = false;
12051200

12061201
start_task(task, stop_observe_task, NULL);
12071202
}
12081203

1204+
void pbdrv_bluetooth_restart_observing_request(void) {
1205+
observe_restart_requested = true;
1206+
process_poll(&pbdrv_bluetooth_spi_process);
1207+
}
1208+
12091209
// Driver interrupt callbacks
12101210

12111211
void pbdrv_bluetooth_stm32_cc2640_srdy_irq(bool srdy) {
@@ -2250,7 +2250,7 @@ PROCESS_THREAD(pbdrv_bluetooth_spi_process, ev, data) {
22502250
spi_set_mrdy(false);
22512251
bluetooth_reset(RESET_STATE_OUT_LOW);
22522252
bluetooth_ready = pybricks_notify_en = uart_tx_notify_en =
2253-
is_broadcasting = is_observing = observe_restart_enabled = false;
2253+
is_broadcasting = is_observing = observe_restart_requested = false;
22542254
conn_handle = peripheral_singleton.con_handle = NO_CONNECTION;
22552255

22562256
pbio_task_t *task;
@@ -2309,11 +2309,14 @@ PROCESS_THREAD(pbdrv_bluetooth_spi_process, ev, data) {
23092309
for (;;) {
23102310
PROCESS_WAIT_UNTIL({
23112311
for (;;) {
2312-
if (observe_restart_enabled && etimer_expired(&observe_restart_timer)) {
2312+
if (observe_restart_requested && pbdrv_clock_get_ms() - observe_restart_time > OBSERVE_RESTART_INTERVAL) {
23132313
static pbio_task_t observe_restart_stop_task;
23142314
static pbio_task_t observe_restart_start_task;
23152315
pbdrv_bluetooth_start_observing_callback_t callback = observe_callback;
23162316

2317+
// Avoid queueing this more than once.
2318+
observe_restart_time = pbdrv_clock_get_ms();
2319+
23172320
pbdrv_bluetooth_stop_observing(&observe_restart_stop_task);
23182321
pbdrv_bluetooth_start_observing(&observe_restart_start_task, callback);
23192322
}

pybricks/common/pb_type_ble.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,12 @@ static mp_obj_t pb_module_ble_observe(mp_obj_t self_in, mp_obj_t channel_in) {
440440

441441
// Have not received data yet or timed out.
442442
if (ch_data.rssi == INT8_MIN) {
443+
444+
#if PBDRV_CONFIG_BLUETOOTH_STM32_CC2640
445+
extern void pbdrv_bluetooth_restart_observing_request(void);
446+
pbdrv_bluetooth_restart_observing_request();
447+
#endif
448+
443449
return mp_const_none;
444450
}
445451

0 commit comments

Comments
 (0)