Kaynağa Gözat

Keep SHCI for unsupported Radio Stack (#960)

* bt: don't stop shci on wrong stack. Start radios stack if FUS is running
* bt: code clean up, f6 target sync

Co-authored-by: あく <alleteam@gmail.com>
gornekich 4 yıl önce
ebeveyn
işleme
70a9823e05

+ 19 - 0
firmware/targets/f6/ble_glue/ble_glue.c

@@ -179,6 +179,25 @@ bool ble_glue_is_radio_stack_ready() {
     return ble_glue->status == BleGlueStatusRadioStackStarted;
 }
 
+bool ble_glue_radio_stack_fw_launch_started() {
+    bool ret = false;
+    // Get FUS status
+    SHCI_FUS_GetState_ErrorCode_t err_code = 0;
+    uint8_t state = SHCI_C2_FUS_GetState(&err_code);
+    if(state == FUS_STATE_VALUE_IDLE) {
+        // When FUS is running we can't read radio stack version correctly
+        // Trying to start radio stack fw, which leads to reset
+        FURI_LOG_W(TAG, "FUS is running. Restart to launch Radio Stack");
+        SHCI_CmdStatus_t status = SHCI_C2_FUS_StartWs();
+        if(status) {
+            FURI_LOG_E(TAG, "Failed to start Radio Stack with status: %02X", status);
+        } else {
+            ret = true;
+        }
+    }
+    return ret;
+}
+
 static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
     switch(status) {
     case SHCI_TL_CmdBusy:

+ 7 - 0
firmware/targets/f6/ble_glue/ble_glue.h

@@ -43,8 +43,15 @@ void ble_glue_set_key_storage_changed_callback(
     BleGlueKeyStorageChangedCallback callback,
     void* context);
 
+/** Stop SHCI thread */
 void ble_glue_thread_stop();
 
+/** Restart MCU to launch radio stack firmware if necessary
+ *
+ * @return      true on radio stack start command
+ */
+bool ble_glue_radio_stack_fw_launch_started();
+
 #ifdef __cplusplus
 }
 #endif

+ 6 - 2
firmware/targets/f6/furi_hal/furi_hal_bt.c

@@ -122,11 +122,15 @@ bool furi_hal_bt_start_radio_stack() {
             ble_glue_thread_stop();
             break;
         }
+        // If FUS is running, start radio stack fw
+        if(ble_glue_radio_stack_fw_launch_started()) {
+            // If FUS is running do nothing and wait for system reset
+            furi_crash("Waiting for FUS to launch radio stack firmware");
+        }
         // Check weather we support radio stack
         if(!furi_hal_bt_radio_stack_is_supported(&info)) {
             FURI_LOG_E(TAG, "Unsupported radio stack");
-            LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
-            ble_glue_thread_stop();
+            // Don't stop SHCI for crypto enclave support
             break;
         }
         // Starting radio stack

+ 19 - 0
firmware/targets/f7/ble_glue/ble_glue.c

@@ -179,6 +179,25 @@ bool ble_glue_is_radio_stack_ready() {
     return ble_glue->status == BleGlueStatusRadioStackStarted;
 }
 
+bool ble_glue_radio_stack_fw_launch_started() {
+    bool ret = false;
+    // Get FUS status
+    SHCI_FUS_GetState_ErrorCode_t err_code = 0;
+    uint8_t state = SHCI_C2_FUS_GetState(&err_code);
+    if(state == FUS_STATE_VALUE_IDLE) {
+        // When FUS is running we can't read radio stack version correctly
+        // Trying to start radio stack fw, which leads to reset
+        FURI_LOG_W(TAG, "FUS is running. Restart to launch Radio Stack");
+        SHCI_CmdStatus_t status = SHCI_C2_FUS_StartWs();
+        if(status) {
+            FURI_LOG_E(TAG, "Failed to start Radio Stack with status: %02X", status);
+        } else {
+            ret = true;
+        }
+    }
+    return ret;
+}
+
 static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
     switch(status) {
     case SHCI_TL_CmdBusy:

+ 7 - 0
firmware/targets/f7/ble_glue/ble_glue.h

@@ -43,8 +43,15 @@ void ble_glue_set_key_storage_changed_callback(
     BleGlueKeyStorageChangedCallback callback,
     void* context);
 
+/** Stop SHCI thread */
 void ble_glue_thread_stop();
 
+/** Restart MCU to launch radio stack firmware if necessary
+ *
+ * @return      true on radio stack start command
+ */
+bool ble_glue_radio_stack_fw_launch_started();
+
 #ifdef __cplusplus
 }
 #endif

+ 6 - 2
firmware/targets/f7/furi_hal/furi_hal_bt.c

@@ -122,11 +122,15 @@ bool furi_hal_bt_start_radio_stack() {
             ble_glue_thread_stop();
             break;
         }
+        // If FUS is running, start radio stack fw
+        if(ble_glue_radio_stack_fw_launch_started()) {
+            // If FUS is running do nothing and wait for system reset
+            furi_crash("Waiting for FUS to launch radio stack firmware");
+        }
         // Check weather we support radio stack
         if(!furi_hal_bt_radio_stack_is_supported(&info)) {
             FURI_LOG_E(TAG, "Unsupported radio stack");
-            LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
-            ble_glue_thread_stop();
+            // Don't stop SHCI for crypto enclave support
             break;
         }
         // Starting radio stack