BleGlue: reorder initialization sequence, move core2 start to early stage. (#816)
This commit is contained in:
parent
70d0519178
commit
b2356c7318
@ -19,6 +19,16 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ble_glue_system_cmd_b
|
|||||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_system_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_system_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
|
||||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_ble_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_ble_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Stage 1: core2 startup and FUS
|
||||||
|
BleGlueStatusStartup,
|
||||||
|
BleGlueStatusBroken,
|
||||||
|
BleGlueStatusFusStarted,
|
||||||
|
// Stage 2: radio stack
|
||||||
|
BleGlueStatusRadioStackStarted,
|
||||||
|
BleGlueStatusRadioStackMissing
|
||||||
|
} BleGlueStatus;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
osMutexId_t shci_mtx;
|
osMutexId_t shci_mtx;
|
||||||
osSemaphoreId_t shci_sem;
|
osSemaphoreId_t shci_sem;
|
||||||
@ -35,13 +45,6 @@ static void ble_glue_user_event_thread(void *argument);
|
|||||||
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status);
|
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status);
|
||||||
static void ble_glue_sys_user_event_callback(void* pPayload);
|
static void ble_glue_sys_user_event_callback(void* pPayload);
|
||||||
|
|
||||||
BleGlueStatus ble_glue_get_status() {
|
|
||||||
if(!ble_glue) {
|
|
||||||
return BleGlueStatusUninitialized;
|
|
||||||
}
|
|
||||||
return ble_glue->status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
||||||
furi_assert(ble_glue);
|
furi_assert(ble_glue);
|
||||||
furi_assert(callback);
|
furi_assert(callback);
|
||||||
@ -96,6 +99,68 @@ void ble_glue_init() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ble_glue_wait_status(BleGlueStatus status) {
|
||||||
|
bool ret = false;
|
||||||
|
size_t countdown = 1000;
|
||||||
|
while (countdown > 0) {
|
||||||
|
if (ble_glue->status == status) {
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
countdown--;
|
||||||
|
osDelay(1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_start() {
|
||||||
|
furi_assert(ble_glue);
|
||||||
|
|
||||||
|
if (!ble_glue_wait_status(BleGlueStatusFusStarted)) {
|
||||||
|
// shutdown core2 power
|
||||||
|
FURI_LOG_E(TAG, "Core2 catastrophic failure, cutting its power");
|
||||||
|
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||||||
|
ble_glue->status = BleGlueStatusBroken;
|
||||||
|
furi_hal_power_insomnia_exit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
furi_hal_power_insomnia_enter();
|
||||||
|
if(ble_app_init()) {
|
||||||
|
FURI_LOG_I(TAG, "Radio stack started");
|
||||||
|
ble_glue->status = BleGlueStatusRadioStackStarted;
|
||||||
|
ret = true;
|
||||||
|
if(SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7) == SHCI_Success) {
|
||||||
|
FURI_LOG_I(TAG, "Flash activity control switched to SEM7");
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Failed to switch flash activity control to SEM7");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Radio stack startup failed");
|
||||||
|
ble_glue->status = BleGlueStatusRadioStackMissing;
|
||||||
|
}
|
||||||
|
furi_hal_power_insomnia_exit();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_is_alive() {
|
||||||
|
if(!ble_glue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_glue->status >= BleGlueStatusFusStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_is_radio_stack_ready() {
|
||||||
|
if(!ble_glue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_glue->status == BleGlueStatusRadioStackStarted;
|
||||||
|
}
|
||||||
|
|
||||||
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
|
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SHCI_TL_CmdBusy:
|
case SHCI_TL_CmdBusy:
|
||||||
@ -126,18 +191,8 @@ static void ble_glue_sys_user_event_callback( void * pPayload ) {
|
|||||||
TL_AsynchEvt_t *p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
TL_AsynchEvt_t *p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
||||||
|
|
||||||
if(p_sys_event->subevtcode == SHCI_SUB_EVT_CODE_READY) {
|
if(p_sys_event->subevtcode == SHCI_SUB_EVT_CODE_READY) {
|
||||||
if(ble_app_init()) {
|
FURI_LOG_I(TAG, "Fus started");
|
||||||
FURI_LOG_I(TAG, "BLE stack started");
|
ble_glue->status = BleGlueStatusFusStarted;
|
||||||
ble_glue->status = BleGlueStatusStarted;
|
|
||||||
if(SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7) == SHCI_Success) {
|
|
||||||
FURI_LOG_I(TAG, "Flash activity control switched to SEM7");
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "Failed to switch flash activity control to SEM7");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "BLE stack startup failed");
|
|
||||||
ble_glue->status = BleGlueStatusBleStackMissing;
|
|
||||||
}
|
|
||||||
furi_hal_power_insomnia_exit();
|
furi_hal_power_insomnia_exit();
|
||||||
} else if(p_sys_event->subevtcode == SHCI_SUB_EVT_ERROR_NOTIF) {
|
} else if(p_sys_event->subevtcode == SHCI_SUB_EVT_ERROR_NOTIF) {
|
||||||
FURI_LOG_E(TAG, "Error during initialization");
|
FURI_LOG_E(TAG, "Error during initialization");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -8,17 +9,33 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void(*BleGlueKeyStorageChangedCallback)(uint8_t* change_addr_start, uint16_t size, void* context);
|
typedef void(*BleGlueKeyStorageChangedCallback)(uint8_t* change_addr_start, uint16_t size, void* context);
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BleGlueStatusUninitialized,
|
|
||||||
BleGlueStatusStartup,
|
|
||||||
BleGlueStatusBleStackMissing,
|
|
||||||
BleGlueStatusStarted
|
|
||||||
} BleGlueStatus;
|
|
||||||
|
|
||||||
|
/** Initialize start core2 and initialize transport */
|
||||||
void ble_glue_init();
|
void ble_glue_init();
|
||||||
|
|
||||||
BleGlueStatus ble_glue_get_status();
|
/** Start Core2 Radio stack
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
*/
|
||||||
|
bool ble_glue_start();
|
||||||
|
|
||||||
|
/** Is core2 alive and at least FUS is running
|
||||||
|
*
|
||||||
|
* @return true if core2 is alive
|
||||||
|
*/
|
||||||
|
bool ble_glue_is_alive();
|
||||||
|
|
||||||
|
/** Is core2 radio stack present and ready
|
||||||
|
*
|
||||||
|
* @return true if present and ready
|
||||||
|
*/
|
||||||
|
bool ble_glue_is_radio_stack_ready();
|
||||||
|
|
||||||
|
/** Set callback for NVM in RAM changes
|
||||||
|
*
|
||||||
|
* @param[in] callback The callback to call on NVM change
|
||||||
|
* @param context The context for callback
|
||||||
|
*/
|
||||||
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context);
|
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -374,7 +374,7 @@ static void gap_advetise_timer_callback(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool gap_init(BleEventCallback on_event_cb, void* context) {
|
bool gap_init(BleEventCallback on_event_cb, void* context) {
|
||||||
if (ble_glue_get_status() != BleGlueStatusStarted) {
|
if (!ble_glue_is_radio_stack_ready()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,19 @@
|
|||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
|
#define TAG "FuriHalBt"
|
||||||
|
|
||||||
osMutexId_t furi_hal_bt_core2_mtx = NULL;
|
osMutexId_t furi_hal_bt_core2_mtx = NULL;
|
||||||
|
|
||||||
void furi_hal_bt_init() {
|
void furi_hal_bt_init() {
|
||||||
furi_hal_bt_core2_mtx = osMutexNew(NULL);
|
furi_hal_bt_core2_mtx = osMutexNew(NULL);
|
||||||
|
furi_assert(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
|
// Explicitly tell that we are in charge of CLK48 domain
|
||||||
|
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
||||||
|
|
||||||
|
// Start Core2
|
||||||
|
ble_glue_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_lock_core2() {
|
void furi_hal_bt_lock_core2() {
|
||||||
@ -22,30 +31,16 @@ void furi_hal_bt_unlock_core2() {
|
|||||||
furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK);
|
furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool furi_hal_bt_wait_startup() {
|
|
||||||
uint16_t counter = 0;
|
|
||||||
while (!(ble_glue_get_status() == BleGlueStatusStarted || ble_glue_get_status() == BleGlueStatusBleStackMissing)) {
|
|
||||||
osDelay(10);
|
|
||||||
counter++;
|
|
||||||
if (counter > 1000) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool furi_hal_bt_start_core2() {
|
bool furi_hal_bt_start_core2() {
|
||||||
furi_assert(furi_hal_bt_core2_mtx);
|
furi_assert(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
bool ret = false;
|
|
||||||
osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever);
|
osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever);
|
||||||
// Explicitly tell that we are in charge of CLK48 domain
|
// Explicitly tell that we are in charge of CLK48 domain
|
||||||
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
||||||
// Start Core2
|
// Start Core2
|
||||||
ble_glue_init();
|
bool ret = ble_glue_start();
|
||||||
// Wait for Core2 start
|
|
||||||
ret = furi_hal_bt_wait_startup();
|
|
||||||
osMutexRelease(furi_hal_bt_core2_mtx);
|
osMutexRelease(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,14 +79,8 @@ bool furi_hal_bt_tx(uint8_t* data, uint16_t size) {
|
|||||||
return serial_svc_update_tx(data, size);
|
return serial_svc_update_tx(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) {
|
void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) {
|
||||||
bool ret = false;
|
ble_app_get_key_storage_buff(key_buff_addr, key_buff_size);
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
|
||||||
if(status == BleGlueStatusUninitialized || BleGlueStatusStarted) {
|
|
||||||
ble_app_get_key_storage_buff(key_buff_addr, key_buff_size);
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_set_key_storage_change_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
void furi_hal_bt_set_key_storage_change_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
||||||
@ -110,8 +99,7 @@ void furi_hal_bt_nvm_sram_sem_release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_dump_state(string_t buffer) {
|
void furi_hal_bt_dump_state(string_t buffer) {
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if (furi_hal_bt_is_alive()) {
|
||||||
if (status == BleGlueStatusStarted) {
|
|
||||||
uint8_t HCI_Version;
|
uint8_t HCI_Version;
|
||||||
uint16_t HCI_Revision;
|
uint16_t HCI_Revision;
|
||||||
uint8_t LMP_PAL_Version;
|
uint8_t LMP_PAL_Version;
|
||||||
@ -132,8 +120,7 @@ void furi_hal_bt_dump_state(string_t buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_alive() {
|
bool furi_hal_bt_is_alive() {
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
return ble_glue_is_alive();
|
||||||
return (status == BleGlueStatusBleStackMissing) || (status == BleGlueStatusStarted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_active() {
|
bool furi_hal_bt_is_active() {
|
||||||
|
@ -127,8 +127,7 @@ static void furi_hal_flash_begin(bool erase_flag) {
|
|||||||
furi_hal_bt_lock_core2();
|
furi_hal_bt_lock_core2();
|
||||||
|
|
||||||
// If Core2 is running use IPC locking
|
// If Core2 is running use IPC locking
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if(furi_hal_bt_is_alive()) {
|
||||||
if(status == BleGlueStatusStarted || status == BleGlueStatusBleStackMissing) {
|
|
||||||
furi_hal_flash_begin_with_core2(erase_flag);
|
furi_hal_flash_begin_with_core2(erase_flag);
|
||||||
} else {
|
} else {
|
||||||
furi_hal_flash_unlock();
|
furi_hal_flash_unlock();
|
||||||
@ -159,8 +158,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) {
|
|||||||
|
|
||||||
static void furi_hal_flash_end(bool erase_flag) {
|
static void furi_hal_flash_end(bool erase_flag) {
|
||||||
// If Core2 is running use IPC locking
|
// If Core2 is running use IPC locking
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if(furi_hal_bt_is_alive()) {
|
||||||
if(status == BleGlueStatusStarted || status == BleGlueStatusBleStackMissing) {
|
|
||||||
furi_hal_flash_end_with_core2(erase_flag);
|
furi_hal_flash_end_with_core2(erase_flag);
|
||||||
} else {
|
} else {
|
||||||
furi_hal_flash_lock();
|
furi_hal_flash_lock();
|
||||||
|
@ -19,6 +19,16 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ble_glue_system_cmd_b
|
|||||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_system_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_system_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
|
||||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_ble_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
|
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_ble_spare_event_buff[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Stage 1: core2 startup and FUS
|
||||||
|
BleGlueStatusStartup,
|
||||||
|
BleGlueStatusBroken,
|
||||||
|
BleGlueStatusFusStarted,
|
||||||
|
// Stage 2: radio stack
|
||||||
|
BleGlueStatusRadioStackStarted,
|
||||||
|
BleGlueStatusRadioStackMissing
|
||||||
|
} BleGlueStatus;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
osMutexId_t shci_mtx;
|
osMutexId_t shci_mtx;
|
||||||
osSemaphoreId_t shci_sem;
|
osSemaphoreId_t shci_sem;
|
||||||
@ -35,13 +45,6 @@ static void ble_glue_user_event_thread(void *argument);
|
|||||||
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status);
|
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status);
|
||||||
static void ble_glue_sys_user_event_callback(void* pPayload);
|
static void ble_glue_sys_user_event_callback(void* pPayload);
|
||||||
|
|
||||||
BleGlueStatus ble_glue_get_status() {
|
|
||||||
if(!ble_glue) {
|
|
||||||
return BleGlueStatusUninitialized;
|
|
||||||
}
|
|
||||||
return ble_glue->status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
||||||
furi_assert(ble_glue);
|
furi_assert(ble_glue);
|
||||||
furi_assert(callback);
|
furi_assert(callback);
|
||||||
@ -96,6 +99,68 @@ void ble_glue_init() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ble_glue_wait_status(BleGlueStatus status) {
|
||||||
|
bool ret = false;
|
||||||
|
size_t countdown = 1000;
|
||||||
|
while (countdown > 0) {
|
||||||
|
if (ble_glue->status == status) {
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
countdown--;
|
||||||
|
osDelay(1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_start() {
|
||||||
|
furi_assert(ble_glue);
|
||||||
|
|
||||||
|
if (!ble_glue_wait_status(BleGlueStatusFusStarted)) {
|
||||||
|
// shutdown core2 power
|
||||||
|
FURI_LOG_E(TAG, "Core2 catastrophic failure, cutting its power");
|
||||||
|
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||||||
|
ble_glue->status = BleGlueStatusBroken;
|
||||||
|
furi_hal_power_insomnia_exit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
furi_hal_power_insomnia_enter();
|
||||||
|
if(ble_app_init()) {
|
||||||
|
FURI_LOG_I(TAG, "Radio stack started");
|
||||||
|
ble_glue->status = BleGlueStatusRadioStackStarted;
|
||||||
|
ret = true;
|
||||||
|
if(SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7) == SHCI_Success) {
|
||||||
|
FURI_LOG_I(TAG, "Flash activity control switched to SEM7");
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Failed to switch flash activity control to SEM7");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FURI_LOG_E(TAG, "Radio stack startup failed");
|
||||||
|
ble_glue->status = BleGlueStatusRadioStackMissing;
|
||||||
|
}
|
||||||
|
furi_hal_power_insomnia_exit();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_is_alive() {
|
||||||
|
if(!ble_glue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_glue->status >= BleGlueStatusFusStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_glue_is_radio_stack_ready() {
|
||||||
|
if(!ble_glue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_glue->status == BleGlueStatusRadioStackStarted;
|
||||||
|
}
|
||||||
|
|
||||||
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
|
static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SHCI_TL_CmdBusy:
|
case SHCI_TL_CmdBusy:
|
||||||
@ -126,18 +191,8 @@ static void ble_glue_sys_user_event_callback( void * pPayload ) {
|
|||||||
TL_AsynchEvt_t *p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
TL_AsynchEvt_t *p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
|
||||||
|
|
||||||
if(p_sys_event->subevtcode == SHCI_SUB_EVT_CODE_READY) {
|
if(p_sys_event->subevtcode == SHCI_SUB_EVT_CODE_READY) {
|
||||||
if(ble_app_init()) {
|
FURI_LOG_I(TAG, "Fus started");
|
||||||
FURI_LOG_I(TAG, "BLE stack started");
|
ble_glue->status = BleGlueStatusFusStarted;
|
||||||
ble_glue->status = BleGlueStatusStarted;
|
|
||||||
if(SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7) == SHCI_Success) {
|
|
||||||
FURI_LOG_I(TAG, "Flash activity control switched to SEM7");
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "Failed to switch flash activity control to SEM7");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "BLE stack startup failed");
|
|
||||||
ble_glue->status = BleGlueStatusBleStackMissing;
|
|
||||||
}
|
|
||||||
furi_hal_power_insomnia_exit();
|
furi_hal_power_insomnia_exit();
|
||||||
} else if(p_sys_event->subevtcode == SHCI_SUB_EVT_ERROR_NOTIF) {
|
} else if(p_sys_event->subevtcode == SHCI_SUB_EVT_ERROR_NOTIF) {
|
||||||
FURI_LOG_E(TAG, "Error during initialization");
|
FURI_LOG_E(TAG, "Error during initialization");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -8,17 +9,33 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void(*BleGlueKeyStorageChangedCallback)(uint8_t* change_addr_start, uint16_t size, void* context);
|
typedef void(*BleGlueKeyStorageChangedCallback)(uint8_t* change_addr_start, uint16_t size, void* context);
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BleGlueStatusUninitialized,
|
|
||||||
BleGlueStatusStartup,
|
|
||||||
BleGlueStatusBleStackMissing,
|
|
||||||
BleGlueStatusStarted
|
|
||||||
} BleGlueStatus;
|
|
||||||
|
|
||||||
|
/** Initialize start core2 and initialize transport */
|
||||||
void ble_glue_init();
|
void ble_glue_init();
|
||||||
|
|
||||||
BleGlueStatus ble_glue_get_status();
|
/** Start Core2 Radio stack
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
*/
|
||||||
|
bool ble_glue_start();
|
||||||
|
|
||||||
|
/** Is core2 alive and at least FUS is running
|
||||||
|
*
|
||||||
|
* @return true if core2 is alive
|
||||||
|
*/
|
||||||
|
bool ble_glue_is_alive();
|
||||||
|
|
||||||
|
/** Is core2 radio stack present and ready
|
||||||
|
*
|
||||||
|
* @return true if present and ready
|
||||||
|
*/
|
||||||
|
bool ble_glue_is_radio_stack_ready();
|
||||||
|
|
||||||
|
/** Set callback for NVM in RAM changes
|
||||||
|
*
|
||||||
|
* @param[in] callback The callback to call on NVM change
|
||||||
|
* @param context The context for callback
|
||||||
|
*/
|
||||||
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context);
|
void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -374,7 +374,7 @@ static void gap_advetise_timer_callback(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool gap_init(BleEventCallback on_event_cb, void* context) {
|
bool gap_init(BleEventCallback on_event_cb, void* context) {
|
||||||
if (ble_glue_get_status() != BleGlueStatusStarted) {
|
if (!ble_glue_is_radio_stack_ready()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,19 @@
|
|||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
|
#define TAG "FuriHalBt"
|
||||||
|
|
||||||
osMutexId_t furi_hal_bt_core2_mtx = NULL;
|
osMutexId_t furi_hal_bt_core2_mtx = NULL;
|
||||||
|
|
||||||
void furi_hal_bt_init() {
|
void furi_hal_bt_init() {
|
||||||
furi_hal_bt_core2_mtx = osMutexNew(NULL);
|
furi_hal_bt_core2_mtx = osMutexNew(NULL);
|
||||||
|
furi_assert(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
|
// Explicitly tell that we are in charge of CLK48 domain
|
||||||
|
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
||||||
|
|
||||||
|
// Start Core2
|
||||||
|
ble_glue_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_lock_core2() {
|
void furi_hal_bt_lock_core2() {
|
||||||
@ -22,30 +31,16 @@ void furi_hal_bt_unlock_core2() {
|
|||||||
furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK);
|
furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool furi_hal_bt_wait_startup() {
|
|
||||||
uint16_t counter = 0;
|
|
||||||
while (!(ble_glue_get_status() == BleGlueStatusStarted || ble_glue_get_status() == BleGlueStatusBleStackMissing)) {
|
|
||||||
osDelay(10);
|
|
||||||
counter++;
|
|
||||||
if (counter > 1000) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool furi_hal_bt_start_core2() {
|
bool furi_hal_bt_start_core2() {
|
||||||
furi_assert(furi_hal_bt_core2_mtx);
|
furi_assert(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
bool ret = false;
|
|
||||||
osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever);
|
osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever);
|
||||||
// Explicitly tell that we are in charge of CLK48 domain
|
// Explicitly tell that we are in charge of CLK48 domain
|
||||||
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
|
||||||
// Start Core2
|
// Start Core2
|
||||||
ble_glue_init();
|
bool ret = ble_glue_start();
|
||||||
// Wait for Core2 start
|
|
||||||
ret = furi_hal_bt_wait_startup();
|
|
||||||
osMutexRelease(furi_hal_bt_core2_mtx);
|
osMutexRelease(furi_hal_bt_core2_mtx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,14 +79,8 @@ bool furi_hal_bt_tx(uint8_t* data, uint16_t size) {
|
|||||||
return serial_svc_update_tx(data, size);
|
return serial_svc_update_tx(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) {
|
void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) {
|
||||||
bool ret = false;
|
ble_app_get_key_storage_buff(key_buff_addr, key_buff_size);
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
|
||||||
if(status == BleGlueStatusUninitialized || BleGlueStatusStarted) {
|
|
||||||
ble_app_get_key_storage_buff(key_buff_addr, key_buff_size);
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_set_key_storage_change_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
void furi_hal_bt_set_key_storage_change_callback(BleGlueKeyStorageChangedCallback callback, void* context) {
|
||||||
@ -110,8 +99,7 @@ void furi_hal_bt_nvm_sram_sem_release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_dump_state(string_t buffer) {
|
void furi_hal_bt_dump_state(string_t buffer) {
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if (furi_hal_bt_is_alive()) {
|
||||||
if (status == BleGlueStatusStarted) {
|
|
||||||
uint8_t HCI_Version;
|
uint8_t HCI_Version;
|
||||||
uint16_t HCI_Revision;
|
uint16_t HCI_Revision;
|
||||||
uint8_t LMP_PAL_Version;
|
uint8_t LMP_PAL_Version;
|
||||||
@ -132,8 +120,7 @@ void furi_hal_bt_dump_state(string_t buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_alive() {
|
bool furi_hal_bt_is_alive() {
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
return ble_glue_is_alive();
|
||||||
return (status == BleGlueStatusBleStackMissing) || (status == BleGlueStatusStarted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_active() {
|
bool furi_hal_bt_is_active() {
|
||||||
|
@ -127,8 +127,7 @@ static void furi_hal_flash_begin(bool erase_flag) {
|
|||||||
furi_hal_bt_lock_core2();
|
furi_hal_bt_lock_core2();
|
||||||
|
|
||||||
// If Core2 is running use IPC locking
|
// If Core2 is running use IPC locking
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if(furi_hal_bt_is_alive()) {
|
||||||
if(status == BleGlueStatusStarted || status == BleGlueStatusBleStackMissing) {
|
|
||||||
furi_hal_flash_begin_with_core2(erase_flag);
|
furi_hal_flash_begin_with_core2(erase_flag);
|
||||||
} else {
|
} else {
|
||||||
furi_hal_flash_unlock();
|
furi_hal_flash_unlock();
|
||||||
@ -159,8 +158,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) {
|
|||||||
|
|
||||||
static void furi_hal_flash_end(bool erase_flag) {
|
static void furi_hal_flash_end(bool erase_flag) {
|
||||||
// If Core2 is running use IPC locking
|
// If Core2 is running use IPC locking
|
||||||
BleGlueStatus status = ble_glue_get_status();
|
if(furi_hal_bt_is_alive()) {
|
||||||
if(status == BleGlueStatusStarted || status == BleGlueStatusBleStackMissing) {
|
|
||||||
furi_hal_flash_end_with_core2(erase_flag);
|
furi_hal_flash_end_with_core2(erase_flag);
|
||||||
} else {
|
} else {
|
||||||
furi_hal_flash_lock();
|
furi_hal_flash_lock();
|
||||||
|
@ -69,12 +69,10 @@ bool furi_hal_bt_is_alive();
|
|||||||
|
|
||||||
/** Get key storage buffer address and size
|
/** Get key storage buffer address and size
|
||||||
*
|
*
|
||||||
* @param key_buff_addr pointer to store buffer address
|
* @param key_buff_addr pointer to store buffer address
|
||||||
* @param key_buff_size pointer to store buffer size
|
* @param key_buff_size pointer to store buffer size
|
||||||
*
|
|
||||||
* @return true on success
|
|
||||||
*/
|
*/
|
||||||
bool furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size);
|
void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size);
|
||||||
|
|
||||||
/** Get SRAM2 hardware semaphore
|
/** Get SRAM2 hardware semaphore
|
||||||
* @note Must be called before SRAM2 read/write operations
|
* @note Must be called before SRAM2 read/write operations
|
||||||
|
Loading…
Reference in New Issue
Block a user