Skip to content

Commit

Permalink
Wait until full BLE reset before re-initializing upon error
Browse files Browse the repository at this point in the history
  • Loading branch information
hedgecrw committed Jan 11, 2024
1 parent c0deb15 commit 3f4bbe5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*************************************************************************************************/

#include <string.h>
#include "bluetooth.h"
#include "wsf_types.h"
#include "wsf_queue.h"
#include "wsf_timer.h"
Expand Down Expand Up @@ -187,6 +188,7 @@ void hciCmdTimeout(wsfMsgHdr_t *pMsg)
// reset/reboot controller and initialize HCI
// layer and SPI transport layer again.

bluetooth_set_uninitialized();
HciDrvRadioShutdown();
HciDrvRadioBoot(0);
DmDevReset();
Expand Down
1 change: 1 addition & 0 deletions software/firmware/src/peripherals/include/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void bluetooth_deinit(void);
void bluetooth_reset(void);
void bluetooth_start(void);
bool bluetooth_is_initialized(void);
void bluetooth_set_uninitialized(void);
void bluetooth_register_discovery_callback(ble_discovery_callback_t callback);
uint8_t bluetooth_get_current_ranging_role(void);
void bluetooth_set_current_ranging_role(uint8_t ranging_role);
Expand Down
51 changes: 27 additions & 24 deletions software/firmware/src/peripherals/src/bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

// Static Global Variables ---------------------------------------------------------------------------------------------

static volatile uint16_t connection_mtu, scan_complete_count, scan_reset_count;
static volatile uint16_t connection_mtu;
static volatile bool is_scanning, is_advertising, is_changing_roles, is_connected, ranges_requested;
static volatile bool data_requested, expected_scanning, expected_advertising, is_initialized, first_initialization;
static volatile uint8_t adv_data_conn[HCI_ADV_DATA_LEN], scan_data_conn[HCI_ADV_DATA_LEN], current_ranging_role[3];
Expand All @@ -28,8 +28,8 @@ static ble_discovery_callback_t discovery_callback;
// Bluetooth LE Advertising and Connection Parameters ------------------------------------------------------------------

static const appAdvCfg_t ble_adv_cfg = {
{ BLE_ADVERTISING_DURATION_MS, BLE_ADVERTISING_DURATION_MS, BLE_ADVERTISING_DURATION_MS },
{ BLE_ADVERTISING_INTERVAL_0_625_MS, BLE_ADVERTISING_INTERVAL_0_625_MS, BLE_ADVERTISING_INTERVAL_0_625_MS }
{ BLE_ADVERTISING_DURATION_MS, BLE_ADVERTISING_DURATION_MS, BLE_ADVERTISING_DURATION_MS },
{ BLE_ADVERTISING_INTERVAL_0_625_MS, BLE_ADVERTISING_INTERVAL_0_625_MS, BLE_ADVERTISING_INTERVAL_0_625_MS }
};
static const appSlaveCfg_t ble_slave_cfg = { MAX_NUM_CONNECTIONS };
static const appSecCfg_t ble_sec_cfg = { 0, 0, 0, FALSE, FALSE };
Expand Down Expand Up @@ -110,20 +110,10 @@ void appUiBtnPoll(void) {}

void am_timer03_isr(void)
{
// Check if a full BLE scanning cycle completed
// Force stop the BLE scanning cycle
am_hal_timer_interrupt_clear(AM_HAL_TIMER_MASK(BLE_SCAN_PROBLEM_TIMER_NUMBER, AM_HAL_TIMER_COMPARE_BOTH));
if (scan_reset_count++)
{
print("TotTag BLE: Scanning cycle did not complete as expected...resetting BLE\n");
bluetooth_reset();
}
else if (!scan_complete_count)
{
DmScanStop();
am_hal_timer_clear(BLE_SCAN_PROBLEM_TIMER_NUMBER);
print("TotTag BLE: Scanning cycle did not complete as expected...re-enabling scanning\n");
DmScanStart(HCI_SCAN_PHY_LE_1M_BIT, ble_master_cfg.discMode, &ble_master_cfg.scanType, FALSE, ble_master_cfg.scanDuration, 0);
}
am_hal_timer_clear(BLE_SCAN_PROBLEM_TIMER_NUMBER);
DmScanStop();
}

static void deviceManagerCallback(dmEvt_t *pDmEvt)
Expand All @@ -136,7 +126,6 @@ static void deviceManagerCallback(dmEvt_t *pDmEvt)
print("TotTag BLE: deviceManagerCallback: Received DM_RESET_CMPL_IND\n");
if (first_initialization)
AttsCalculateDbHash();
advertising_setup();
is_advertising = is_scanning = is_changing_roles = first_initialization = false;
is_initialized = true;
if (expected_advertising)
Expand Down Expand Up @@ -178,7 +167,6 @@ static void deviceManagerCallback(dmEvt_t *pDmEvt)
case DM_SCAN_STOP_IND:
print("TotTag BLE: deviceManagerCallback: Received DM_SCAN_STOP_IND\n");
is_scanning = false;
++scan_complete_count;
if (is_initialized && expected_scanning)
bluetooth_start_scanning();
break;
Expand All @@ -202,6 +190,8 @@ static void deviceManagerCallback(dmEvt_t *pDmEvt)
break;
case DM_HW_ERROR_IND:
print("TotTag BLE: deviceManagerCallback: Received DM_HW_ERROR_IND...Rebooting BLE\n");
bluetooth_set_uninitialized();
HciDrvRadioShutdown();
HciDrvRadioBoot(false);
DmDevReset();
break;
Expand Down Expand Up @@ -269,6 +259,8 @@ void bluetooth_init(uint8_t* uid)
am_hal_timer_config(BLE_SCAN_PROBLEM_TIMER_NUMBER, &scan_error_timer_config);
am_hal_timer_interrupt_enable(AM_HAL_TIMER_MASK(BLE_SCAN_PROBLEM_TIMER_NUMBER, AM_HAL_TIMER_COMPARE0));
NVIC_SetPriority(TIMER0_IRQn + BLE_SCAN_PROBLEM_TIMER_NUMBER, NVIC_configKERNEL_INTERRUPT_PRIORITY);
NVIC_SetPriority(COOPER_IOM_IRQn, NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_SetPriority(AM_COOPER_IRQn, NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(TIMER0_IRQn + BLE_SCAN_PROBLEM_TIMER_NUMBER);

// Set the Bluetooth address and boot the BLE radio
Expand All @@ -279,11 +271,15 @@ void bluetooth_init(uint8_t* uid)

void bluetooth_deinit(void)
{
// Stop all running timers
am_hal_timer_disable(BLE_SCAN_PROBLEM_TIMER_NUMBER);
NVIC_DisableIRQ(TIMER0_IRQn + BLE_SCAN_PROBLEM_TIMER_NUMBER);
am_hal_timer_interrupt_disable(AM_HAL_TIMER_MASK(BLE_SCAN_PROBLEM_TIMER_NUMBER, AM_HAL_TIMER_COMPARE0));

// Shut down the BLE controller
HciDrvRadioShutdown();
NVIC_DisableIRQ(AM_COOPER_IRQn);
NVIC_DisableIRQ(TIMER0_IRQn + BLE_SCAN_PROBLEM_TIMER_NUMBER);
am_hal_timer_interrupt_disable(AM_HAL_TIMER_MASK(BLE_SCAN_PROBLEM_TIMER_NUMBER, AM_HAL_TIMER_COMPARE0));
NVIC_DisableIRQ(COOPER_IOM_IRQn);
is_initialized = is_advertising = is_scanning = false;

// Put the BLE controller into reset
Expand All @@ -296,7 +292,7 @@ void bluetooth_deinit(void)
void bluetooth_reset(void)
{
// Shutdown and reboot the BLE controller
is_initialized = is_advertising = is_scanning = false;
bluetooth_set_uninitialized();
HciDrvRadioShutdown();
HciDrvRadioBoot(false);
DmDevReset();
Expand Down Expand Up @@ -334,6 +330,13 @@ bool bluetooth_is_initialized(void)
return is_initialized;
}

void bluetooth_set_uninitialized(void)
{
// Force all initialization and activity flags to false
is_initialized = is_advertising = is_scanning = false;
am_hal_timer_disable(BLE_SCAN_PROBLEM_TIMER_NUMBER);
}

void bluetooth_register_discovery_callback(ble_discovery_callback_t callback)
{
// Store the device discovery callback
Expand Down Expand Up @@ -375,6 +378,7 @@ void bluetooth_start_advertising(void)
expected_advertising = true;
if (is_initialized && !is_advertising)
{
advertising_setup();
print("TotTag BLE: Starting advertising...\n");
AppAdvStart(APP_MODE_CONNECTABLE);
}
Expand All @@ -401,12 +405,11 @@ void bluetooth_start_scanning(void)
{
// Attempt to start scanning
expected_scanning = true;
scan_complete_count = scan_reset_count = 0;
if (is_initialized && !is_scanning)
{
print("TotTag BLE: Starting scanning...\n");
am_hal_timer_clear(BLE_SCAN_PROBLEM_TIMER_NUMBER);
DmScanStart(HCI_SCAN_PHY_LE_1M_BIT, ble_master_cfg.discMode, &ble_master_cfg.scanType, FALSE, ble_master_cfg.scanDuration, 0);
DmScanStart(HCI_SCAN_PHY_LE_1M_BIT, ble_master_cfg.discMode, &ble_master_cfg.scanType, TRUE, ble_master_cfg.scanDuration, 0);
}
}

Expand All @@ -427,7 +430,7 @@ void bluetooth_reset_scanning(void)
// Attempt to stop scanning without changing the scanning expectation
if (is_initialized && is_scanning)
{
am_hal_timer_disable(BLE_SCAN_PROBLEM_TIMER_NUMBER);
am_hal_timer_clear(BLE_SCAN_PROBLEM_TIMER_NUMBER);
DmScanStop();
}
}
Expand Down

0 comments on commit 3f4bbe5

Please sign in to comment.