From f77b3e6cf9779d72ea5a444d298aa7f29f267caa Mon Sep 17 00:00:00 2001 From: RocketGod <57732082+RocketGod-git@users.noreply.github.com> Date: Sat, 20 Dec 2025 22:37:10 -0800 Subject: [PATCH] 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. --- dist/proto_pirate.fap | Bin 94708 -> 98024 bytes helpers/radio_device_loader.c | 48 +++++++++++++++++++++++++--- helpers/radio_device_loader.h | 7 ++-- protopirate_app.c | 8 +++-- scenes/protopirate_scene_receiver.c | 28 +++++++++++++--- views/protopirate_receiver.c | 19 ++++++----- 6 files changed, 86 insertions(+), 24 deletions(-) diff --git a/dist/proto_pirate.fap b/dist/proto_pirate.fap index d9fcb5682e13a14f58e3b5031b22aa5a4cc05f8c..77e4da7627271646c4b897863e1be2bfd8365057 100644 GIT binary patch delta 46547 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 delta 43242 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 WzOIf@NrERIxV0Ln0tSGA1_l7cY?!+M diff --git a/helpers/radio_device_loader.c b/helpers/radio_device_loader.c index b25091e..050b2b3 100644 --- a/helpers/radio_device_loader.c +++ b/helpers/radio_device_loader.c @@ -3,6 +3,10 @@ #include #include +#include +#include + +#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"); } } \ No newline at end of file diff --git a/helpers/radio_device_loader.h b/helpers/radio_device_loader.h index 509b756..b7bcb0c 100644 --- a/helpers/radio_device_loader.h +++ b/helpers/radio_device_loader.h @@ -3,18 +3,19 @@ #include +#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); \ No newline at end of file diff --git a/protopirate_app.c b/protopirate_app.c index fbdcd4e..aff570a 100644 --- a/protopirate_app.c +++ b/protopirate_app.c @@ -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) diff --git a/scenes/protopirate_scene_receiver.c b/scenes/protopirate_scene_receiver.c index ef38503..cfa353e 100644 --- a/scenes/protopirate_scene_receiver.c +++ b/scenes/protopirate_scene_receiver.c @@ -2,7 +2,6 @@ #include "../protopirate_app_i.h" #include "../helpers/protopirate_storage.h" #include -#include #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; diff --git a/views/protopirate_receiver.c b/views/protopirate_receiver.c index b36d127..8a51537 100644 --- a/views/protopirate_receiver.c +++ b/views/protopirate_receiver.c @@ -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"); }