Merge pull request #2562 from dhalbert/ble-fixes
nrf: track vm_used_ble better
This commit is contained in:
commit
298bca3fdd
|
@ -145,6 +145,9 @@ void SD_EVT_IRQHandler(void) {
|
||||||
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
|
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (it != NULL) {
|
while (it != NULL) {
|
||||||
|
#if CIRCUITPY_VERBOSE_BLE
|
||||||
|
// mp_printf(&mp_plat_print, " calling handler: 0x%08lx, param: 0x%08lx\n", it->func-1, it->param);
|
||||||
|
#endif
|
||||||
done = it->func(event, it->param) || done;
|
done = it->func(event, it->param) || done;
|
||||||
it = it->next;
|
it = it->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,6 +437,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
|
||||||
.active = active
|
.active = active
|
||||||
};
|
};
|
||||||
uint32_t err_code;
|
uint32_t err_code;
|
||||||
|
vm_used_ble = true;
|
||||||
err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
|
err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
|
||||||
|
|
||||||
if (err_code != NRF_SUCCESS) {
|
if (err_code != NRF_SUCCESS) {
|
||||||
|
@ -511,6 +512,7 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
|
||||||
ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
|
ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
|
||||||
event_info.done = false;
|
event_info.done = false;
|
||||||
|
|
||||||
|
vm_used_ble = true;
|
||||||
uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
|
uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
|
||||||
|
|
||||||
if (err_code != NRF_SUCCESS) {
|
if (err_code != NRF_SUCCESS) {
|
||||||
|
@ -615,6 +617,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
|
||||||
return err_code;
|
return err_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm_used_ble = true;
|
||||||
err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
|
err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
|
||||||
if (err_code != NRF_SUCCESS) {
|
if (err_code != NRF_SUCCESS) {
|
||||||
return err_code;
|
return err_code;
|
||||||
|
@ -709,6 +712,11 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
|
||||||
adapter->connection_objs = NULL;
|
adapter->connection_objs = NULL;
|
||||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||||
bleio_connection_internal_t *connection = &bleio_connections[i];
|
bleio_connection_internal_t *connection = &bleio_connections[i];
|
||||||
|
// Disconnect all connections with Python state cleanly. Keep any supervisor-only connections.
|
||||||
|
if (connection->connection_obj != mp_const_none &&
|
||||||
|
connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
|
||||||
|
common_hal_bleio_connection_disconnect(connection);
|
||||||
|
}
|
||||||
connection->connection_obj = mp_const_none;
|
connection->connection_obj = mp_const_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,13 +91,14 @@ void check_sec_status(uint8_t sec_status) {
|
||||||
void bleio_reset() {
|
void bleio_reset() {
|
||||||
bleio_adapter_reset(&common_hal_bleio_adapter_obj);
|
bleio_adapter_reset(&common_hal_bleio_adapter_obj);
|
||||||
if (!vm_used_ble) {
|
if (!vm_used_ble) {
|
||||||
|
// No user-code BLE operations were done, so we can maintain the supervisor state.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
|
if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
|
||||||
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
|
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
|
||||||
}
|
}
|
||||||
supervisor_start_bluetooth();
|
|
||||||
bonding_reset();
|
bonding_reset();
|
||||||
|
supervisor_start_bluetooth();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The singleton _bleio.Adapter object, bound to _bleio.adapter
|
// 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_
|
||||||
while (nrf_error == NRF_ERROR_BUSY) {
|
while (nrf_error == NRF_ERROR_BUSY) {
|
||||||
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
|
nrf_error = sd_ble_gattc_read(conn_handle, handle, 0);
|
||||||
}
|
}
|
||||||
check_nrf_error(nrf_error);
|
if (nrf_error != NRF_SUCCESS) {
|
||||||
|
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
|
||||||
|
check_nrf_error(nrf_error);
|
||||||
|
}
|
||||||
|
|
||||||
while (!read_info.done) {
|
while (!read_info.done) {
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
}
|
}
|
||||||
check_gatt_status(read_info.status);
|
|
||||||
|
|
||||||
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
|
ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
|
||||||
|
check_gatt_status(read_info.status);
|
||||||
return read_info.final_len;
|
return read_info.final_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,14 +267,15 @@ void bonding_background(void) {
|
||||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||||
bleio_connection_internal_t *connection = &bleio_connections[i];
|
bleio_connection_internal_t *connection = &bleio_connections[i];
|
||||||
|
|
||||||
uint64_t current_ticks_ms = supervisor_ticks_ms64();
|
|
||||||
// Wait at least one second before saving CCCD, to consolidate
|
// Wait at least one second before saving CCCD, to consolidate
|
||||||
// writes that involve multiple CCCDs. For instance, for HID,
|
// writes that involve multiple CCCDs. For instance, for HID,
|
||||||
// three CCCD's are set in short succession by the HID client.
|
// three CCCD's are set in short succession by the HID client.
|
||||||
if (connection->do_bond_cccds &&
|
if (connection->do_bond_cccds) {
|
||||||
current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
|
uint64_t current_ticks_ms = supervisor_ticks_ms64();
|
||||||
write_sys_attr_block(connection);
|
if (current_ticks_ms - connection->do_bond_cccds_request_time >= 1000) {
|
||||||
connection->do_bond_cccds = false;
|
write_sys_attr_block(connection);
|
||||||
|
connection->do_bond_cccds = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection->do_bond_keys) {
|
if (connection->do_bond_keys) {
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
#include "shared-bindings/microcontroller/Processor.h"
|
#include "shared-bindings/microcontroller/Processor.h"
|
||||||
|
|
||||||
#include "supervisor/filesystem.h"
|
#include "supervisor/filesystem.h"
|
||||||
|
#include "supervisor/port.h"
|
||||||
#include "supervisor/shared/safe_mode.h"
|
#include "supervisor/shared/safe_mode.h"
|
||||||
#include "nrfx_glue.h"
|
#include "nrfx_glue.h"
|
||||||
|
#include "nrf_nvic.h"
|
||||||
|
|
||||||
// This routine should work even when interrupts are disabled. Used by OneWire
|
// This routine should work even when interrupts are disabled. Used by OneWire
|
||||||
// for precise timing.
|
// for precise timing.
|
||||||
|
@ -46,10 +48,38 @@ void common_hal_mcu_delay_us(uint32_t delay) {
|
||||||
NRFX_DELAY_US(delay);
|
NRFX_DELAY_US(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static volatile uint32_t nesting_count = 0;
|
||||||
|
static uint8_t is_nested_critical_region;
|
||||||
|
static uint8_t sd_is_enabled = false;
|
||||||
void common_hal_mcu_disable_interrupts() {
|
void common_hal_mcu_disable_interrupts() {
|
||||||
|
sd_softdevice_is_enabled(&sd_is_enabled);
|
||||||
|
if (sd_is_enabled) {
|
||||||
|
sd_nvic_critical_region_enter(&is_nested_critical_region);
|
||||||
|
} else {
|
||||||
|
__disable_irq();
|
||||||
|
__DMB();
|
||||||
|
nesting_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_mcu_enable_interrupts() {
|
void common_hal_mcu_enable_interrupts() {
|
||||||
|
// Don't check here if SD is enabled, because we'll crash if interrupts
|
||||||
|
// were turned off and sd_softdevice_is_enabled is called.
|
||||||
|
if (sd_is_enabled) {
|
||||||
|
sd_nvic_critical_region_exit(is_nested_critical_region);
|
||||||
|
} else {
|
||||||
|
if (nesting_count == 0) {
|
||||||
|
// This is very very bad because it means there was mismatched disable/enables so we
|
||||||
|
// crash.
|
||||||
|
reset_into_safe_mode(HARD_CRASH);
|
||||||
|
}
|
||||||
|
nesting_count--;
|
||||||
|
if (nesting_count > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__DMB();
|
||||||
|
__enable_irq();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||||
|
|
Loading…
Reference in New Issue