diff --git a/applications/external/spectrum_analyzer/helpers/radio_device_loader.c b/applications/external/spectrum_analyzer/helpers/radio_device_loader.c new file mode 100644 index 000000000..d2cffde58 --- /dev/null +++ b/applications/external/spectrum_analyzer/helpers/radio_device_loader.c @@ -0,0 +1,64 @@ +#include "radio_device_loader.h" + +#include +#include + +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(); + if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) { + subghz_devices_end(radio_device); + } +} \ No newline at end of file diff --git a/applications/external/spectrum_analyzer/helpers/radio_device_loader.h b/applications/external/spectrum_analyzer/helpers/radio_device_loader.h new file mode 100644 index 000000000..bee4e2c36 --- /dev/null +++ b/applications/external/spectrum_analyzer/helpers/radio_device_loader.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +/** 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); \ No newline at end of file diff --git a/applications/external/spectrum_analyzer/spectrum_analyzer.c b/applications/external/spectrum_analyzer/spectrum_analyzer.c index 26e41f0ce..84ef293c3 100644 --- a/applications/external/spectrum_analyzer/spectrum_analyzer.c +++ b/applications/external/spectrum_analyzer/spectrum_analyzer.c @@ -389,14 +389,6 @@ void spectrum_analyzer_free(SpectrumAnalyzer* instance) { free(instance->model); free(instance); - - furi_hal_subghz_idle(); - furi_hal_subghz_sleep(); - - // Disable power for External CC1101 if it was enabled and module is connected - furi_hal_subghz_disable_ext_power(); - // Reinit SPI handles for internal radio / nfc - furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } int32_t spectrum_analyzer_app(void* p) { @@ -405,21 +397,18 @@ int32_t spectrum_analyzer_app(void* p) { SpectrumAnalyzer* spectrum_analyzer = spectrum_analyzer_alloc(); InputEvent input; - // Enable power for External CC1101 if it is connected - furi_hal_subghz_enable_ext_power(); - // Auto switch to internal radio if external radio is not available - furi_delay_ms(15); - if(!furi_hal_subghz_check_radio()) { - furi_hal_subghz_select_radio_type(SubGhzRadioInternal); - furi_hal_subghz_init_radio_type(SubGhzRadioInternal); - } - furi_hal_power_suppress_charge_enter(); FURI_LOG_D("Spectrum", "Main Loop - Starting worker"); furi_delay_ms(50); spectrum_analyzer_worker_start(spectrum_analyzer->worker); + spectrum_analyzer_calculate_frequencies(spectrum_analyzer->model); + spectrum_analyzer_worker_set_frequencies( + spectrum_analyzer->worker, + spectrum_analyzer->model->channel0_frequency, + spectrum_analyzer->model->spacing, + spectrum_analyzer->model->width); FURI_LOG_D("Spectrum", "Main Loop - Wait on queue"); furi_delay_ms(50); diff --git a/applications/external/spectrum_analyzer/spectrum_analyzer_worker.c b/applications/external/spectrum_analyzer/spectrum_analyzer_worker.c index e670d2808..5b35a47a2 100644 --- a/applications/external/spectrum_analyzer/spectrum_analyzer_worker.c +++ b/applications/external/spectrum_analyzer/spectrum_analyzer_worker.c @@ -4,6 +4,8 @@ #include #include +#include "helpers/radio_device_loader.h" + #include struct SpectrumAnalyzerWorker { @@ -13,6 +15,8 @@ struct SpectrumAnalyzerWorker { SpectrumAnalyzerWorkerCallback callback; void* callback_context; + const SubGhzDevice* radio_device; + uint32_t channel0_frequency; uint32_t spacing; uint8_t width; @@ -44,7 +48,9 @@ void spectrum_analyzer_worker_set_filter(SpectrumAnalyzerWorker* instance) { filter_config[0][1] = 0x6C; /* 196 kHz / .8 = 245 kHz --> 270 kHz */ break; } - furi_hal_subghz_load_registers((uint8_t*)filter_config); + + UNUSED(filter_config); + // furi_hal_subghz_load_registers((uint8_t*)filter_config); } static int32_t spectrum_analyzer_worker_thread(void* context) { @@ -54,32 +60,53 @@ static int32_t spectrum_analyzer_worker_thread(void* context) { FURI_LOG_D("SpectrumWorker", "spectrum_analyzer_worker_thread: Start"); // Start CC1101 - furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); - furi_hal_subghz_set_frequency(433920000); - furi_hal_subghz_flush_rx(); - furi_hal_subghz_rx(); + subghz_devices_reset(instance->radio_device); + subghz_devices_load_preset(instance->radio_device, FuriHalSubGhzPresetOok650Async, NULL); + subghz_devices_set_frequency(instance->radio_device, 433920000); + subghz_devices_flush_rx(instance->radio_device); + subghz_devices_set_rx(instance->radio_device); - static const uint8_t radio_config[][2] = { - {CC1101_FSCTRL1, 0x12}, - {CC1101_FSCTRL0, 0x00}, + const uint8_t radio_config[] = { - {CC1101_AGCCTRL2, 0xC0}, + CC1101_FSCTRL0, + 0x00, + CC1101_FSCTRL1, + 0x12, + + CC1101_AGCCTRL2, + 0xC0, + + CC1101_MDMCFG4, + 0x6C, + CC1101_TEST2, + 0x88, + CC1101_TEST1, + 0x31, + CC1101_TEST0, + 0x09, - {CC1101_MDMCFG4, 0x6C}, - {CC1101_TEST2, 0x88}, - {CC1101_TEST1, 0x31}, - {CC1101_TEST0, 0x09}, /* End */ - {0, 0}, + 0, + 0, + + // ook_async_patable + 0x00, + 0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; while(instance->should_work) { furi_delay_ms(50); // FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop"); - furi_hal_subghz_idle(); - furi_hal_subghz_load_registers((uint8_t*)radio_config); + subghz_devices_idle(instance->radio_device); + subghz_devices_load_preset( + instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)radio_config); // TODO: Check filter! // spectrum_analyzer_worker_set_filter(instance); @@ -90,9 +117,15 @@ static int32_t spectrum_analyzer_worker_thread(void* context) { for(uint8_t ch_offset = 0, chunk = 0; ch_offset < CHUNK_SIZE; ++chunk >= NUM_CHUNKS && ++ch_offset && (chunk = 0)) { uint8_t ch = chunk * CHUNK_SIZE + ch_offset; - furi_hal_subghz_set_frequency(instance->channel0_frequency + (ch * instance->spacing)); - furi_hal_subghz_rx(); + if(subghz_devices_is_frequency_valid( + instance->radio_device, + instance->channel0_frequency + (ch * instance->spacing))) + subghz_devices_set_frequency( + instance->radio_device, + instance->channel0_frequency + (ch * instance->spacing)); + + subghz_devices_set_rx(instance->radio_device); furi_delay_ms(3); // dec dBm @@ -100,7 +133,7 @@ static int32_t spectrum_analyzer_worker_thread(void* context) { //max_ss = 0 -> -74.0 //max_ss = 255 -> -74.5 //max_ss = 128 -> -138.0 - instance->channel_ss[ch] = (furi_hal_subghz_get_rssi() + 138) * 2; + instance->channel_ss[ch] = (subghz_devices_get_rssi(instance->radio_device) + 138) * 2; if(instance->channel_ss[ch] > instance->max_rssi_dec) { instance->max_rssi_dec = instance->channel_ss[ch]; @@ -108,7 +141,7 @@ static int32_t spectrum_analyzer_worker_thread(void* context) { instance->max_rssi_channel = ch; } - furi_hal_subghz_idle(); + subghz_devices_idle(instance->radio_device); } // FURI_LOG_T("SpectrumWorker", "channel_ss[0]: %u", instance->channel_ss[0]); @@ -138,6 +171,11 @@ SpectrumAnalyzerWorker* spectrum_analyzer_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, spectrum_analyzer_worker_thread); + subghz_devices_init(); + + instance->radio_device = + radio_device_loader_set(instance->radio_device, SubGhzRadioDeviceTypeExternalCC1101); + FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_alloc: End"); return instance; @@ -147,6 +185,12 @@ void spectrum_analyzer_worker_free(SpectrumAnalyzerWorker* instance) { FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_free"); furi_assert(instance); furi_thread_free(instance->thread); + + subghz_devices_sleep(instance->radio_device); + radio_device_loader_end(instance->radio_device); + + subghz_devices_deinit(); + free(instance); }