Explorar o código

Add experimental support for an external radio

This code was contributed by xMasterX.
twisted_pear %!s(int64=2) %!d(string=hai) anos
pai
achega
481a690204

+ 24 - 5
esubghz_chat.c

@@ -1,8 +1,8 @@
 #include <furi_hal.h>
 #include <gui/elements.h>
 #include <gui/gui.h>
-#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
 
+#include "helpers/radio_device_loader.h"
 #include "esubghz_chat_i.h"
 
 #define CHAT_LEAVE_DELAY 10
@@ -137,17 +137,29 @@ void tx_msg_input(ESubGhzChatState *state)
 			tx_size);
 }
 
-/* Displays whether or not encryption has been enabled in the text box. Also
- * clears the text input buffer to remove the password and starts the Sub-GHz
- * worker. After starting the worker a join message is transmitted. */
+/* Displays information on frequency, encryption and radio type in the text
+ * box. Also clears the text input buffer to remove the password and starts the
+ * Sub-GHz worker. After starting the worker a join message is transmitted. */
 void enter_chat(ESubGhzChatState *state)
 {
+	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
+			state->frequency);
+
 	furi_string_cat_printf(state->chat_box_store, "\nEncrypted: %s",
 			(state->encrypted ? "yes" : "no"));
 
 	subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
 			state->frequency);
 
+	if (strcmp(state->subghz_device->name, "cc1101_ext") == 0) {
+		furi_string_cat_printf(state->chat_box_store,
+				"\nRadio: External");
+	} else {
+		furi_string_cat_printf(state->chat_box_store,
+				"\nRadio: Internal");
+	}
+
+
 	/* concatenate the name prefix and join message */
 	furi_string_set(state->msg_input, state->name_prefix);
 	furi_string_cat_str(state->msg_input, " joined chat.");
@@ -572,7 +584,12 @@ int32_t esubghz_chat(void)
 
 	/* init internal device */
 	subghz_devices_init();
-	state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+
+	state->subghz_device = radio_device_loader_set(state->subghz_device,
+			SubGhzRadioDeviceTypeExternalCC1101);
+
+	subghz_devices_reset(state->subghz_device);
+	subghz_devices_idle(state->subghz_device);
 
 	/* set chat name prefix */
 	furi_string_printf(state->name_prefix, "%s",
@@ -678,6 +695,8 @@ int32_t esubghz_chat(void)
 	crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData));
 
 	/* deinit devices */
+	radio_device_loader_end(state->subghz_device);
+
 	subghz_devices_deinit();
 
 	/* exit suppress charge mode */

+ 0 - 0
nfc_helpers.h → helpers/nfc_helpers.h


+ 65 - 0
helpers/radio_device_loader.c

@@ -0,0 +1,65 @@
+#include "radio_device_loader.h"
+
+#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
+#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
+
+static void radio_device_loader_power_on() {
+    uint8_t attempts = 0;
+    while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+        furi_hal_power_enable_otg();
+        //CC1101 power-up time
+        furi_delay_ms(10);
+    }
+}
+
+static void radio_device_loader_power_off() {
+    if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
+}
+
+bool radio_device_loader_is_connect_external(const char* name) {
+    bool is_connect = false;
+    bool is_otg_enabled = furi_hal_power_is_otg_enabled();
+
+    if(!is_otg_enabled) {
+        radio_device_loader_power_on();
+    }
+
+    const SubGhzDevice* device = subghz_devices_get_by_name(name);
+    if(device) {
+        is_connect = subghz_devices_is_connect(device);
+    }
+
+    if(!is_otg_enabled) {
+        radio_device_loader_power_off();
+    }
+    return is_connect;
+}
+
+const SubGhzDevice* radio_device_loader_set(
+    const SubGhzDevice* current_radio_device,
+    SubGhzRadioDeviceType radio_device_type) {
+    const SubGhzDevice* radio_device;
+
+    if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
+       radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
+        radio_device_loader_power_on();
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
+        subghz_devices_begin(radio_device);
+    } else if(current_radio_device == NULL) {
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+    } else {
+        radio_device_loader_end(current_radio_device);
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+    }
+
+    return radio_device;
+}
+
+void radio_device_loader_end(const SubGhzDevice* radio_device) {
+    furi_assert(radio_device);
+    radio_device_loader_power_off();
+    // Code below is not used (and will cause crash) since its called from tx_rx worker end!
+    //if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
+    //    subghz_devices_end(radio_device);
+    //}
+}

+ 15 - 0
helpers/radio_device_loader.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include <lib/subghz/devices/devices.h>
+
+/** SubGhzRadioDeviceType */
+typedef enum {
+    SubGhzRadioDeviceTypeInternal,
+    SubGhzRadioDeviceTypeExternalCC1101,
+} SubGhzRadioDeviceType;
+
+const SubGhzDevice* radio_device_loader_set(
+    const SubGhzDevice* current_radio_device,
+    SubGhzRadioDeviceType radio_device_type);
+
+void radio_device_loader_end(const SubGhzDevice* radio_device);

+ 1 - 5
scenes/esubghz_chat_freq_input.c

@@ -1,15 +1,11 @@
 #include "../esubghz_chat_i.h"
 
-/* Sends FreqEntered event to scene manager and displays the frequency in the
- * text box. */
+/* Sends FreqEntered event to scene manager. */
 static void freq_input_cb(void *context)
 {
 	furi_assert(context);
 	ESubGhzChatState* state = context;
 
-	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
-			state->frequency);
-
 	view_dispatcher_send_custom_event(state->view_dispatcher,
 			ESubGhzChatEvent_FreqEntered);
 }

+ 1 - 1
scenes/esubghz_chat_key_read_popup.c

@@ -1,5 +1,5 @@
 #include "../esubghz_chat_i.h"
-#include "../nfc_helpers.h"
+#include "../helpers/nfc_helpers.h"
 
 typedef enum {
 	KeyReadPopupState_Idle,

+ 1 - 1
scenes/esubghz_chat_key_share_popup.c

@@ -1,5 +1,5 @@
 #include "../esubghz_chat_i.h"
-#include "../nfc_helpers.h"
+#include "../helpers/nfc_helpers.h"
 
 struct ReplayDictNfcWriterContext {
 	uint8_t *cur;