Improve radio device handling and UI indicators

Adds detailed logging and error handling for radio device selection and connection, clarifies external/internal device status throughout the app, and updates the receiver view to display EXT/INT status in the UI. Also refactors code for better maintainability and debugging, ensuring correct device selection and status reporting.
This commit is contained in:
RocketGod committed 2025-12-20 22:37:10 -08:00
1 parent 92645220ad
commit f77b3e6cf9
6 files changed
+86 -24

No files matched your search

BIN
View File
Binary file not shown.
+43 -5
View File
@@ -3,6 +3,10 @@
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#include <furi.h>
#include <furi_hal.h>
#define TAG "RadioDeviceLoader"
static void radio_device_loader_power_on() {
uint8_t attempts = 0;
@@ -11,10 +15,14 @@ static void radio_device_loader_power_on() {
// CC1101 power-up time
furi_delay_ms(10);
}
FURI_LOG_D(TAG, "OTG power enabled after %d attempts", attempts);
}
static void radio_device_loader_power_off() {
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
FURI_LOG_D(TAG, "OTG power disabled");
}
}
bool radio_device_loader_is_connect_external(const char* name) {
@@ -28,6 +36,9 @@ bool radio_device_loader_is_connect_external(const char* name) {
const SubGhzDevice* device = subghz_devices_get_by_name(name);
if(device) {
is_connect = subghz_devices_is_connect(device);
FURI_LOG_D(TAG, "External device '%s' connect check: %s", name, is_connect ? "YES" : "NO");
} else {
FURI_LOG_W(TAG, "Could not get device by name: %s", name);
}
if(!is_otg_enabled) {
@@ -39,32 +50,59 @@ bool radio_device_loader_is_connect_external(const char* name) {
const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type) {
const SubGhzDevice* radio_device;
const SubGhzDevice* radio_device = NULL;
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);
if(radio_device) {
subghz_devices_begin(radio_device);
FURI_LOG_I(TAG, "External CC1101 initialized successfully");
} else {
FURI_LOG_E(TAG, "Failed to get external CC1101 device");
}
} else if(current_radio_device == NULL) {
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
if(radio_device) {
FURI_LOG_I(TAG, "Internal CC1101 selected");
} else {
FURI_LOG_E(TAG, "Failed to load internal CC1101");
}
} else {
radio_device_loader_end(current_radio_device);
radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
FURI_LOG_I(TAG, "Switched to internal CC1101");
}
return radio_device;
}
bool radio_device_loader_is_external(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME));
if(!radio_device) {
FURI_LOG_W(TAG, "is_external called with NULL device");
return false;
}
const SubGhzDevice* internal_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
bool is_external = (radio_device != internal_device);
FURI_LOG_D(TAG, "is_external check: device=%p, internal=%p, result=%s",
radio_device, internal_device, is_external ? "EXTERNAL" : "INTERNAL");
return is_external;
}
void radio_device_loader_end(const SubGhzDevice* radio_device) {
furi_assert(radio_device);
radio_device_loader_power_off();
if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
subghz_devices_end(radio_device);
FURI_LOG_I(TAG, "External radio device ended");
} else {
FURI_LOG_D(TAG, "Internal radio device - no cleanup needed");
}
}
+4 -3
View File
@@ -3,18 +3,19 @@
#include <lib/subghz/devices/devices.h>
#define SUBGHZ_DEVICE_CC1101_INT_NAME "cc1101_int"
#define SUBGHZ_DEVICE_CC1101_EXT_NAME "cc1101_ext"
/** SubGhzRadioDeviceType */
typedef enum {
SubGhzRadioDeviceTypeInternal,
SubGhzRadioDeviceTypeExternalCC1101,
} SubGhzRadioDeviceType;
bool radio_device_loader_is_connect_external(const char* name);
const SubGhzDevice* radio_device_loader_set(
const SubGhzDevice* current_radio_device,
SubGhzRadioDeviceType radio_device_type);
bool radio_device_loader_is_connect_external(const char* name);
bool radio_device_loader_is_external(const SubGhzDevice* radio_device);
void radio_device_loader_end(const SubGhzDevice* radio_device);
+5 -3
View File
@@ -170,15 +170,17 @@ ProtoPirateApp *protopirate_app_alloc()
app->txrx->radio_device =
radio_device_loader_set(NULL, SubGhzRadioDeviceTypeExternalCC1101);
if(!app->txrx->radio_device || !subghz_devices_is_connect(app->txrx->radio_device)) {
FURI_LOG_W(TAG, "External CC1101 not found or failed, using internal CC1101.");
if(!app->txrx->radio_device) {
FURI_LOG_W(TAG, "External CC1101 not found, using internal CC1101.");
app->txrx->radio_device =
radio_device_loader_set(NULL, SubGhzRadioDeviceTypeInternal);
if(!app->txrx->radio_device) {
FURI_LOG_E(TAG, "Failed to initialize internal CC1101.");
} else {
FURI_LOG_I(TAG, "Internal CC1101 initialized successfully.");
}
} else {
FURI_LOG_I(TAG, "CC1101 initialized successfully.");
FURI_LOG_I(TAG, "External CC1101 initialized successfully.");
}
if (!app->txrx->radio_device)
+23 -5
View File
@@ -2,7 +2,6 @@
#include "../protopirate_app_i.h"
#include "../helpers/protopirate_storage.h"
#include <notification/notification_messages.h>
#include <furi_hal_rtc.h>
#define TAG "ProtoPirateSceneRx"
#define KIA_DISPLAY_HISTORY_MAX 50
@@ -18,6 +17,9 @@ static void protopirate_scene_receiver_update_statusbar(void* context) {
protopirate_get_frequency_modulation(app, frequency_str, modulation_str);
// Check if using external radio
bool is_external = radio_device_loader_is_external(app->txrx->radio_device);
// Show auto-save indicator in the history count area
if(app->auto_save) {
furi_string_printf(
@@ -33,12 +35,13 @@ static void protopirate_scene_receiver_update_statusbar(void* context) {
KIA_DISPLAY_HISTORY_MAX);
}
// Pass actual external radio status
protopirate_view_receiver_add_data_statusbar(
app->protopirate_receiver,
furi_string_get_cstr(frequency_str),
furi_string_get_cstr(modulation_str),
furi_string_get_cstr(history_stat_str),
false);
is_external); // <-- Now correctly passes external status
furi_string_free(frequency_str);
furi_string_free(modulation_str);
@@ -90,7 +93,7 @@ static void protopirate_scene_receiver_callback(
furi_string_set_str(protocol, "Unknown");
}
// Clean protocol name for filename (replace / with _)
// Clean protocol name for filename
furi_string_replace_all(protocol, "/", "_");
furi_string_replace_all(protocol, " ", "_");
@@ -98,7 +101,6 @@ static void protopirate_scene_receiver_callback(
if(protopirate_storage_save_capture(
ff, furi_string_get_cstr(protocol), saved_path)) {
FURI_LOG_I(TAG, "Auto-saved: %s", furi_string_get_cstr(saved_path));
// Double vibro to indicate auto-save
notification_message(app->notifications, &sequence_double_vibro);
} else {
FURI_LOG_E(TAG, "Auto-save failed");
@@ -127,7 +129,13 @@ static void protopirate_scene_receiver_callback(
void protopirate_scene_receiver_on_enter(void* context) {
ProtoPirateApp* app = context;
// Log which radio device is being used
bool is_external = radio_device_loader_is_external(app->txrx->radio_device);
const char* device_name = subghz_devices_get_name(app->txrx->radio_device);
FURI_LOG_I(TAG, "=== ENTERING RECEIVER SCENE ===");
FURI_LOG_I(TAG, "Radio device: %s", device_name ? device_name : "NULL");
FURI_LOG_I(TAG, "Is External: %s", is_external ? "YES" : "NO");
FURI_LOG_I(TAG, "Frequency: %lu Hz", app->txrx->preset->frequency);
FURI_LOG_I(TAG, "Modulation: %s", furi_string_get_cstr(app->txrx->preset->name));
FURI_LOG_I(TAG, "Auto-save: %s", app->auto_save ? "ON" : "OFF");
@@ -222,10 +230,20 @@ bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event)
protopirate_scene_receiver_update_statusbar(app);
}
// Update RSSI
// Update RSSI from the correct radio device
if(app->txrx->txrx_state == ProtoPirateTxRxStateRx) {
float rssi = subghz_devices_get_rssi(app->txrx->radio_device);
protopirate_view_receiver_set_rssi(app->protopirate_receiver, rssi);
// Debug: Log RSSI periodically (every ~5 seconds)
static uint8_t rssi_log_counter = 0;
if(++rssi_log_counter >= 50) {
bool is_ext = radio_device_loader_is_external(app->txrx->radio_device);
FURI_LOG_D(TAG, "RSSI: %.1f dBm (%s)",
(double)rssi,
is_ext ? "EXT" : "INT");
rssi_log_counter = 0;
}
}
consumed = true;
+11 -8
View File
@@ -146,6 +146,14 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo
size_t item_count = ProtoPirateReceiverMenuItemArray_size(model->history_item_arr);
bool scrollbar = item_count > MENU_ITEMS;
// Draw EXT/INT indicator in upper right corner
canvas_set_font(canvas, FontSecondary);
if(model->external_radio) {
canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, "EXT");
} else {
canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, "INT");
}
FuriString* str_buff;
str_buff = furi_string_alloc();
@@ -295,9 +303,9 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo
// Preset
canvas_draw_str(canvas, 44, 58, furi_string_get_cstr(model->preset_str));
// History counter
// History counter
canvas_draw_str_aligned(
canvas, 108, 58, AlignCenter, AlignBottom, furi_string_get_cstr(model->history_stat_str));
canvas, 98, 58, AlignCenter, AlignBottom, furi_string_get_cstr(model->history_stat_str));
// Draw RSSI indicator with animation
uint8_t x = 70;
@@ -318,12 +326,7 @@ void protopirate_view_receiver_draw(Canvas* canvas, ProtoPirateReceiverModel* mo
}
}
// External radio indicator
if(model->external_radio) {
canvas_draw_str(canvas, 116, 58, "E");
}
// Lock indicator
// Lock indicator (bottom right, since EXT/INT moved to top)
if(model->lock == ProtoPirateLockOn) {
canvas_draw_str(canvas, 122, 58, "L");
}