Skip to content

Commit 298bca3

Browse files
authored
Merge pull request #2562 from dhalbert/ble-fixes
nrf: track vm_used_ble better
2 parents 0b761f6 + 87f73e2 commit 298bca3

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

ports/nrf/bluetooth/ble_drv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ void SD_EVT_IRQHandler(void) {
145145
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
146146
bool done = false;
147147
while (it != NULL) {
148+
#if CIRCUITPY_VERBOSE_BLE
149+
// mp_printf(&mp_plat_print, " calling handler: 0x%08lx, param: 0x%08lx\n", it->func-1, it->param);
150+
#endif
148151
done = it->func(event, it->param) || done;
149152
it = it->next;
150153
}

ports/nrf/common-hal/_bleio/Adapter.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
437437
.active = active
438438
};
439439
uint32_t err_code;
440+
vm_used_ble = true;
440441
err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
441442

442443
if (err_code != NRF_SUCCESS) {
@@ -511,6 +512,7 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
511512
ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
512513
event_info.done = false;
513514

515+
vm_used_ble = true;
514516
uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
515517

516518
if (err_code != NRF_SUCCESS) {
@@ -615,6 +617,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
615617
return err_code;
616618
}
617619

620+
vm_used_ble = true;
618621
err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
619622
if (err_code != NRF_SUCCESS) {
620623
return err_code;
@@ -709,6 +712,11 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
709712
adapter->connection_objs = NULL;
710713
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
711714
bleio_connection_internal_t *connection = &bleio_connections[i];
715+
// Disconnect all connections with Python state cleanly. Keep any supervisor-only connections.
716+
if (connection->connection_obj != mp_const_none &&
717+
connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
718+
common_hal_bleio_connection_disconnect(connection);
719+
}
712720
connection->connection_obj = mp_const_none;
713721
}
714722
}

ports/nrf/common-hal/_bleio/__init__.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ void check_sec_status(uint8_t sec_status) {
9191
void bleio_reset() {
9292
bleio_adapter_reset(&common_hal_bleio_adapter_obj);
9393
if (!vm_used_ble) {
94+
// No user-code BLE operations were done, so we can maintain the supervisor state.
9495
return;
9596
}
9697
if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
9798
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
9899
}
99-
supervisor_start_bluetooth();
100100
bonding_reset();
101+
supervisor_start_bluetooth();
101102
}
102103

103104
// The singleton _bleio.Adapter object, bound to _bleio.adapter
@@ -195,14 +196,17 @@ size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_
195196
while (nrf_error == NRF_ERROR_BUSY) {
196197
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
197198
}
198-
check_nrf_error(nrf_error);
199+
if (nrf_error != NRF_SUCCESS) {
200+
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
201+
check_nrf_error(nrf_error);
202+
}
199203

200204
while (!read_info.done) {
201205
RUN_BACKGROUND_TASKS;
202206
}
203-
check_gatt_status(read_info.status);
204207

205208
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
209+
check_gatt_status(read_info.status);
206210
return read_info.final_len;
207211
}
208212

ports/nrf/common-hal/_bleio/bonding.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,15 @@ void bonding_background(void) {
267267
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
268268
bleio_connection_internal_t *connection = &bleio_connections[i];
269269

270-
uint64_t current_ticks_ms = supervisor_ticks_ms64();
271270
// Wait at least one second before saving CCCD, to consolidate
272271
// writes that involve multiple CCCDs. For instance, for HID,
273272
// three CCCD's are set in short succession by the HID client.
274-
if (connection->do_bond_cccds &&
275-
current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
276-
write_sys_attr_block(connection);
277-
connection->do_bond_cccds = false;
273+
if (connection->do_bond_cccds) {
274+
uint64_t current_ticks_ms = supervisor_ticks_ms64();
275+
if (current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
276+
write_sys_attr_block(connection);
277+
connection->do_bond_cccds = false;
278+
}
278279
}
279280

280281
if (connection->do_bond_keys) {

ports/nrf/common-hal/microcontroller/__init__.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,49 @@
3737
#include "shared-bindings/microcontroller/Processor.h"
3838

3939
#include "supervisor/filesystem.h"
40+
#include "supervisor/port.h"
4041
#include "supervisor/shared/safe_mode.h"
4142
#include "nrfx_glue.h"
43+
#include "nrf_nvic.h"
4244

4345
// This routine should work even when interrupts are disabled. Used by OneWire
4446
// for precise timing.
4547
void common_hal_mcu_delay_us(uint32_t delay) {
4648
NRFX_DELAY_US(delay);
4749
}
4850

51+
static volatile uint32_t nesting_count = 0;
52+
static uint8_t is_nested_critical_region;
53+
static uint8_t sd_is_enabled = false;
4954
void common_hal_mcu_disable_interrupts() {
55+
sd_softdevice_is_enabled(&sd_is_enabled);
56+
if (sd_is_enabled) {
57+
sd_nvic_critical_region_enter(&is_nested_critical_region);
58+
} else {
59+
__disable_irq();
60+
__DMB();
61+
nesting_count++;
62+
}
5063
}
5164

5265
void common_hal_mcu_enable_interrupts() {
66+
// Don't check here if SD is enabled, because we'll crash if interrupts
67+
// were turned off and sd_softdevice_is_enabled is called.
68+
if (sd_is_enabled) {
69+
sd_nvic_critical_region_exit(is_nested_critical_region);
70+
} else {
71+
if (nesting_count == 0) {
72+
// This is very very bad because it means there was mismatched disable/enables so we
73+
// crash.
74+
reset_into_safe_mode(HARD_CRASH);
75+
}
76+
nesting_count--;
77+
if (nesting_count > 0) {
78+
return;
79+
}
80+
__DMB();
81+
__enable_irq();
82+
}
5383
}
5484

5585
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {

0 commit comments

Comments
 (0)