diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index d59d0ea3c..5f1a02673 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -77,6 +77,7 @@ typedef enum { SubGhzCustomEventSceneAnalyzerLock, SubGhzCustomEventSceneAnalyzerUnlock, SubGhzCustomEventSceneSettingLock, + SubGhzCustomEventSceneSettingResetToDefault, SubGhzCustomEventSceneExit, SubGhzCustomEventSceneStay, diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index c3f8ad445..2d1acafac 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -3,10 +3,9 @@ #include #include #include - #include -#define TAG "SubGhz" +#define TAG "SubGhzTxRx" static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) { UNUSED(instance); @@ -30,8 +29,7 @@ SubGhzTxRx* subghz_txrx_alloc() { instance->preset = malloc(sizeof(SubGhzRadioPreset)); instance->preset->name = furi_string_alloc(); - subghz_txrx_set_preset( - instance, "AM650", subghz_setting_get_default_frequency(instance->setting), NULL, 0); + subghz_txrx_set_default_preset(instance, 0); instance->txrx_state = SubGhzTxRxStateSleep; @@ -380,10 +378,11 @@ void subghz_txrx_hopper_update(SubGhzTxRx* instance) { default: break; } - float rssi = -127.0f; + // Init value isn't using + // float rssi = -127.0f; if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) { // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = subghz_devices_get_rssi(instance->radio_device); + float rssi = subghz_devices_get_rssi(instance->radio_device); // Stay if RSSI is high enough if(rssi > -90.0f) { @@ -404,7 +403,7 @@ void subghz_txrx_hopper_update(SubGhzTxRx* instance) { if(instance->txrx_state == SubGhzTxRxStateRx) { subghz_txrx_rx_end(instance); - }; + } if(instance->txrx_state == SubGhzTxRxStateIDLE) { subghz_receiver_reset(instance->receiver); instance->preset->frequency = @@ -551,7 +550,7 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi subghz_receiver_set_filter(instance->receiver, filter); } -void subghz_txrx_set_rx_calback( +void subghz_txrx_set_rx_callback( SubGhzTxRx* instance, SubGhzReceiverCallback callback, void* context) { @@ -671,4 +670,32 @@ void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { furi_assert(instance); return instance->receiver; -} \ No newline at end of file +} + +void subghz_txrx_set_default_preset(SubGhzTxRx* instance, uint32_t frequency) { + furi_assert(instance); + + const char* default_modulation = "AM650"; + if(frequency == 0) { + frequency = subghz_setting_get_default_frequency(subghz_txrx_get_setting(instance)); + } + subghz_txrx_set_preset(instance, default_modulation, frequency, NULL, 0); +} + +const char* + subghz_txrx_set_preset_internal(SubGhzTxRx* instance, uint32_t frequency, uint8_t index) { + furi_assert(instance); + + SubGhzSetting* setting = subghz_txrx_get_setting(instance); + const char* preset_name = subghz_setting_get_preset_name(setting, index); + subghz_setting_set_default_frequency(setting, frequency); + + subghz_txrx_set_preset( + instance, + preset_name, + frequency, + subghz_setting_get_preset_data(setting, index), + subghz_setting_get_preset_data_size(setting, index)); + + return preset_name; +} diff --git a/applications/main/subghz/helpers/subghz_txrx.h b/applications/main/subghz/helpers/subghz_txrx.h index 12fed2a9b..a0f9f3055 100644 --- a/applications/main/subghz/helpers/subghz_txrx.h +++ b/applications/main/subghz/helpers/subghz_txrx.h @@ -274,7 +274,7 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi * @param callback Callback for receive data * @param context Context for callback */ -void subghz_txrx_set_rx_calback( +void subghz_txrx_set_rx_callback( SubGhzTxRx* instance, SubGhzReceiverCallback callback, void* context); @@ -329,7 +329,7 @@ float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance); */ const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance); -/* Get get intelligence whether frequency the selected radio device to use +/* Get intelligence whether frequency the selected radio device to use * * @param instance Pointer to a SubGhzTxRx * @return bool True if the frequency is valid @@ -344,3 +344,22 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw + +/** + * @brief Set current preset AM650 without additional params + * + * @param instance - instance Pointer to a SubGhzTxRx + * @param frequency - frequency of preset, if pass 0 then taking default frequency 433.92MHz + */ +void subghz_txrx_set_default_preset(SubGhzTxRx* instance, uint32_t frequency); + +/** + * @brief Set current preset by index + * + * @param instance - instance Pointer to a SubGhzTxRx + * @param frequency - frequency of new preset + * @param index - index of preset taken from SubGhzSetting + * @return const char* - name of preset + */ +const char* + subghz_txrx_set_preset_internal(SubGhzTxRx* instance, uint32_t frequency, uint8_t index); diff --git a/applications/main/subghz/scenes/subghz_scene_decode_raw.c b/applications/main/subghz/scenes/subghz_scene_decode_raw.c index 988a61c8b..85a524117 100644 --- a/applications/main/subghz/scenes/subghz_scene_decode_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_decode_raw.c @@ -1,8 +1,4 @@ #include "../subghz_i.h" -#include "../views/receiver.h" -#include - -#include #define TAG "SubGhzDecodeRaw" #define SAMPLES_TO_READ_PER_TICK 400 @@ -21,13 +17,20 @@ static void subghz_scene_receiver_update_statusbar(void* context) { subghz->subghz_receiver, furi_string_get_cstr(frequency_str), furi_string_get_cstr(modulation_str), - furi_string_get_cstr(history_stat_str)); + furi_string_get_cstr(history_stat_str), + subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF, + READ_BIT(subghz->filter, SubGhzProtocolFlag_BinRAW) > 0); furi_string_free(frequency_str); furi_string_free(modulation_str); } else { subghz_view_receiver_add_data_statusbar( - subghz->subghz_receiver, furi_string_get_cstr(history_stat_str), "", ""); + subghz->subghz_receiver, + furi_string_get_cstr(history_stat_str), + "", + "", + subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF, + READ_BIT(subghz->filter, SubGhzProtocolFlag_BinRAW) > 0); } furi_string_free(history_stat_str); } @@ -154,7 +157,7 @@ void subghz_scene_decode_raw_on_enter(void* context) { subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_decode_raw_callback, subghz); - subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); + subghz_txrx_set_rx_callback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_Decodable); @@ -170,7 +173,7 @@ void subghz_scene_decode_raw_on_enter(void* context) { } else { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); - for(uint8_t i = 0; i < subghz_history_get_item(subghz->history); i++) { + for(uint16_t i = 0; i < subghz_history_get_item(subghz->history); i++) { furi_string_reset(item_name); furi_string_reset(item_time); subghz_history_get_text_item_menu(subghz->history, item_name, i); @@ -202,7 +205,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart); subghz->idx_menu_chosen = 0; - subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); + subghz_txrx_set_rx_callback(subghz->txrx, NULL, subghz); if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); diff --git a/applications/main/subghz/scenes/subghz_scene_delete_raw.c b/applications/main/subghz/scenes/subghz_scene_delete_raw.c index ada0f4c5c..ec6b93653 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_raw.c @@ -1,5 +1,5 @@ +#include "../subghz.h" #include "../subghz_i.h" -#include "../helpers/subghz_custom_event.h" void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index b1071d836..27b7abbf4 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -60,6 +60,9 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer); if(frequency > 0) { subghz->last_settings->frequency = frequency; +#ifdef FURI_DEBUG + subghz_last_settings_log(subghz->last_settings); +#endif subghz_last_settings_save(subghz->last_settings); } diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 1e56604ea..22d78d68d 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -104,8 +104,15 @@ void subghz_scene_read_raw_on_enter(void* context) { if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); +#if SUBGHZ_LAST_SETTING_SAVE_PRESET + if(furi_string_empty(file_name)) { + subghz_txrx_set_preset_internal( + subghz->txrx, + subghz->last_settings->frequency, + subghz->last_settings->preset_index); + } +#endif } - furi_string_free(file_name); subghz_scene_read_raw_update_statusbar(subghz); //set callback view raw @@ -115,6 +122,8 @@ void subghz_scene_read_raw_on_enter(void* context) { //set filter RAW feed subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_RAW); + furi_string_free(file_name); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW); } @@ -139,10 +148,9 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { } else { //Restore default setting if(subghz->raw_send_only) { - subghz_set_default_preset(subghz); + subghz_txrx_set_default_preset(subghz->txrx, 0); } else { - subghz_txrx_set_preset( - subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); + subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency); } if(!scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneSaved)) { diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 14c88c7e4..9dc48965d 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -1,5 +1,4 @@ #include "../subghz_i.h" -#include "../views/receiver.h" #include #include @@ -70,13 +69,20 @@ static void subghz_scene_receiver_update_statusbar(void* context) { subghz->subghz_receiver, furi_string_get_cstr(frequency_str), furi_string_get_cstr(modulation_str), - furi_string_get_cstr(history_stat_str)); + furi_string_get_cstr(history_stat_str), + subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF, + READ_BIT(subghz->filter, SubGhzProtocolFlag_BinRAW) > 0); furi_string_free(frequency_str); furi_string_free(modulation_str); } else { subghz_view_receiver_add_data_statusbar( - subghz->subghz_receiver, furi_string_get_cstr(history_stat_str), "", ""); + subghz->subghz_receiver, + furi_string_get_cstr(history_stat_str), + "", + "", + subghz_txrx_hopper_get_state(subghz->txrx) != SubGhzHopperStateOFF, + READ_BIT(subghz->filter, SubGhzProtocolFlag_BinRAW) > 0); subghz->state_notifications = SubGhzNotificationStateIDLE; } furi_string_free(history_stat_str); @@ -142,7 +148,17 @@ void subghz_scene_receiver_on_enter(void* context) { FuriString* item_time = furi_string_alloc(); if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) { - subghz_txrx_set_preset(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); +#if SUBGHZ_LAST_SETTING_SAVE_PRESET + subghz_txrx_set_preset_internal( + subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index); +#else + subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency); +#endif + + subghz->filter = subghz->last_settings->filter; + subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + subghz->ignore_filter = subghz->last_settings->ignore_filter; + subghz_history_reset(history); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); subghz->idx_menu_chosen = 0; @@ -151,9 +167,9 @@ void subghz_scene_receiver_on_enter(void* context) { subghz_view_receiver_set_lock(subghz->subghz_receiver, subghz_is_locked(subghz)); subghz_view_receiver_set_mode(subghz->subghz_receiver, SubGhzViewReceiverModeLive); - //Load history to receiver + // Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); - for(uint8_t i = 0; i < subghz_history_get_item(history); i++) { + for(uint16_t i = 0; i < subghz_history_get_item(history); i++) { furi_string_reset(item_name); furi_string_reset(item_time); subghz_history_get_text_item_menu(history, item_name, i); @@ -167,13 +183,22 @@ void subghz_scene_receiver_on_enter(void* context) { } furi_string_free(item_name); furi_string_free(item_time); + subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); - subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); + subghz_txrx_set_rx_callback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); if(!subghz_history_get_text_space_left(subghz->history, NULL)) { subghz->state_notifications = SubGhzNotificationStateRx; } + + // Check if hopping was enabled + if(subghz->last_settings->enable_hopping) { + subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateRunning); + } else { + subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); + } + subghz_txrx_rx_start(subghz->txrx); subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen); @@ -199,15 +224,14 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { subghz->state_notifications = SubGhzNotificationStateIDLE; subghz_txrx_stop(subghz->txrx); subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); - subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); + subghz_txrx_set_rx_callback(subghz->txrx, NULL, subghz); if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); } else { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); - subghz_txrx_set_preset( - subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); + subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 62ee53871..aebbc3693 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -1,6 +1,8 @@ #include "../subghz_i.h" #include +#define TAG "SubGhzSceneReceiverConfig" + enum SubGhzSettingIndex { SubGhzSettingIndexFrequency, SubGhzSettingIndexHopping, @@ -10,6 +12,7 @@ enum SubGhzSettingIndex { SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreMagellan, SubGhzSettingIndexSound, + SubGhzSettingIndexResetToDefault, SubGhzSettingIndexLock, SubGhzSettingIndexRAWThresholdRSSI, }; @@ -43,47 +46,51 @@ const float raw_threshold_rssi_value[RAW_THRESHOLD_RSSI_COUNT] = { -40.0f, }; -#define HOPPING_COUNT 2 -const char* const hopping_text[HOPPING_COUNT] = { - "OFF", - "ON", -}; -const uint32_t hopping_value[HOPPING_COUNT] = { +#define COMBO_BOX_COUNT 2 + +const uint32_t hopping_value[COMBO_BOX_COUNT] = { SubGhzHopperStateOFF, SubGhzHopperStateRunning, }; -#define SPEAKER_COUNT 2 -const char* const speaker_text[SPEAKER_COUNT] = { - "OFF", - "ON", -}; -const uint32_t speaker_value[SPEAKER_COUNT] = { +const uint32_t speaker_value[COMBO_BOX_COUNT] = { SubGhzSpeakerStateShutdown, SubGhzSpeakerStateEnable, }; -#define BIN_RAW_COUNT 2 -const char* const bin_raw_text[BIN_RAW_COUNT] = { - "OFF", - "ON", -}; -const uint32_t bin_raw_value[BIN_RAW_COUNT] = { + +const uint32_t bin_raw_value[COMBO_BOX_COUNT] = { SubGhzProtocolFlag_Decodable, SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_BinRAW, }; -#define PROTOCOL_IGNORE_COUNT 2 -const char* const protocol_ignore_text[PROTOCOL_IGNORE_COUNT] = { + +const char* const combobox_text[COMBO_BOX_COUNT] = { "OFF", "ON", }; +static void + subghz_scene_receiver_config_set_ignore_filter(VariableItem* item, SubGhzProtocolFlag filter) { + SubGhz* subghz = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, combobox_text[index]); + + if(index == 0) { + CLEAR_BIT(subghz->ignore_filter, filter); + } else { + SET_BIT(subghz->ignore_filter, filter); + } + + subghz->last_settings->ignore_filter = subghz->ignore_filter; +} + uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { furi_assert(context); SubGhz* subghz = context; SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_frequency_count(setting); i++) { + for(size_t i = 0; i < subghz_setting_get_frequency_count(setting); i++) { if(value == subghz_setting_get_frequency(setting, i)) { index = i; break; @@ -100,7 +107,7 @@ uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void* uint8_t index = 0; SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); - for(uint8_t i = 0; i < subghz_setting_get_preset_count(setting); i++) { + for(size_t i = 0; i < subghz_setting_get_preset_count(setting); i++) { if(!strcmp(subghz_setting_get_preset_name(setting, i), preset_name)) { index = i; break; @@ -111,23 +118,18 @@ uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void* return index; } -uint8_t subghz_scene_receiver_config_hopper_value_index( - const uint32_t value, - const uint32_t values[], - uint8_t values_count, - void* context) { +SubGhzHopperState subghz_scene_receiver_config_hopper_value_index(void* context) { furi_assert(context); - UNUSED(values_count); SubGhz* subghz = context; - if(value == values[0]) { - return 0; + if(subghz_txrx_hopper_get_state(subghz->txrx) == SubGhzHopperStateOFF) { + return SubGhzHopperStateOFF; } else { variable_item_set_current_value_text( (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig), " -----"); - return 1; + return SubGhzHopperStateRunning; } } @@ -180,17 +182,19 @@ static void subghz_scene_receiver_config_set_preset(VariableItem* item) { preset.frequency, subghz_setting_get_preset_data(setting, index), subghz_setting_get_preset_data_size(setting, index)); + subghz->last_settings->preset_index = index; } static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); + SubGhzHopperState index = variable_item_get_current_value_index(item); SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); VariableItem* frequency_item = (VariableItem*)scene_manager_get_scene_state( subghz->scene_manager, SubGhzSceneReceiverConfig); - variable_item_set_current_value_text(item, hopping_text[index]); - if(hopping_value[index] == SubGhzHopperStateOFF) { + variable_item_set_current_value_text(item, combobox_text[(uint8_t)index]); + + if(index == SubGhzHopperStateOFF) { char text_buf[10] = {0}; uint32_t frequency = subghz_setting_get_default_frequency(setting); SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); @@ -203,6 +207,7 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) (frequency % 1000000) / 10000); variable_item_set_current_value_text(frequency_item, text_buf); + // Maybe better add one more function with only with the frequency argument? subghz_txrx_set_preset( subghz->txrx, furi_string_get_cstr(preset.name), @@ -216,15 +221,15 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) variable_item_set_current_value_index( frequency_item, subghz_setting_get_frequency_default_index(setting)); } - - subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[index]); + subghz->last_settings->enable_hopping = index != SubGhzHopperStateOFF; + subghz_txrx_hopper_set_state(subghz->txrx, index); } static void subghz_scene_receiver_config_set_speaker(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, speaker_text[index]); + variable_item_set_current_value_text(item, combobox_text[index]); subghz_txrx_speaker_set_state(subghz->txrx, speaker_value[index]); } @@ -232,9 +237,12 @@ static void subghz_scene_receiver_config_set_bin_raw(VariableItem* item) { SubGhz* subghz = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, bin_raw_text[index]); + variable_item_set_current_value_text(item, combobox_text[index]); subghz->filter = bin_raw_value[index]; subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + + // We can set here, but during subghz_last_settings_save filter was changed to ignore BinRAW + subghz->last_settings->filter = subghz->filter; } static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) { @@ -243,21 +251,10 @@ static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* it variable_item_set_current_value_text(item, raw_threshold_rssi_text[index]); subghz_threshold_rssi_set(subghz->threshold_rssi, raw_threshold_rssi_value[index]); + + subghz->last_settings->rssi = raw_threshold_rssi_value[index]; } -static inline void - subghz_scene_receiver_config_set_ignore_filter(VariableItem* item, SubGhzProtocolFlag filter) { - SubGhz* subghz = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, protocol_ignore_text[index]); - - if(index == 0) { - CLEAR_BIT(subghz->ignore_filter, filter); - } else { - SET_BIT(subghz->ignore_filter, filter); - } -} static inline bool subghz_scene_receiver_config_ignore_filter_get_index( SubGhzProtocolFlag filter, SubGhzProtocolFlag flag) { @@ -282,6 +279,46 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context, if(index == SubGhzSettingIndexLock) { view_dispatcher_send_custom_event( subghz->view_dispatcher, SubGhzCustomEventSceneSettingLock); + } else if(index == SubGhzSettingIndexResetToDefault) { + // Reset all values to default state! +#if SUBGHZ_LAST_SETTING_SAVE_PRESET + subghz_txrx_set_preset_internal( + subghz->txrx, + SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY, + SUBGHZ_LAST_SETTING_DEFAULT_PRESET); +#else + subghz_txrx_set_default_preset(subghz->txrx, SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY); +#endif + SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + const char* preset_name = furi_string_get_cstr(preset.name); + int preset_index = subghz_setting_get_inx_preset_by_name(setting, preset_name); + const int default_index = 0; + + subghz->last_settings->frequency = preset.frequency; + subghz->last_settings->preset_index = preset_index; + + subghz_threshold_rssi_set(subghz->threshold_rssi, raw_threshold_rssi_value[default_index]); + subghz->filter = bin_raw_value[0]; + subghz->ignore_filter = 0x00; + subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + subghz->last_settings->ignore_filter = subghz->ignore_filter; + subghz->last_settings->filter = subghz->filter; + + subghz_txrx_speaker_set_state(subghz->txrx, speaker_value[default_index]); + + subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[default_index]); + subghz->last_settings->enable_hopping = hopping_value[default_index]; + + variable_item_list_set_selected_item(subghz->variable_item_list, default_index); + variable_item_list_reset(subghz->variable_item_list); +#ifdef FURI_DEBUG + subghz_last_settings_log(subghz->last_settings); +#endif + subghz_last_settings_save(subghz->last_settings); + + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventSceneSettingResetToDefault); } } @@ -330,13 +367,13 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, "Hopping:", - HOPPING_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_hopping_running, subghz); - value_index = subghz_scene_receiver_config_hopper_value_index( - subghz_txrx_hopper_get_state(subghz->txrx), hopping_value, HOPPING_COUNT, subghz); + value_index = subghz_scene_receiver_config_hopper_value_index(subghz); + variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, hopping_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != @@ -344,12 +381,13 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, "Bin RAW:", - BIN_RAW_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_bin_raw, subghz); - value_index = value_index_uint32(subghz->filter, bin_raw_value, BIN_RAW_COUNT); + + value_index = value_index_uint32(subghz->filter, bin_raw_value, COMBO_BOX_COUNT); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, bin_raw_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != @@ -357,52 +395,62 @@ void subghz_scene_receiver_config_on_enter(void* context) { item = variable_item_list_add( subghz->variable_item_list, "Ignore Starline:", - PROTOCOL_IGNORE_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_starline, subghz); value_index = subghz_scene_receiver_config_ignore_filter_get_index( subghz->ignore_filter, SubGhzProtocolFlag_StarLine); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, protocol_ignore_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); item = variable_item_list_add( subghz->variable_item_list, "Ignore Cars:", - PROTOCOL_IGNORE_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_auto_alarms, subghz); value_index = subghz_scene_receiver_config_ignore_filter_get_index( subghz->ignore_filter, SubGhzProtocolFlag_AutoAlarms); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, protocol_ignore_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); item = variable_item_list_add( subghz->variable_item_list, "Ignore Magellan:", - PROTOCOL_IGNORE_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_magellan, subghz); value_index = subghz_scene_receiver_config_ignore_filter_get_index( subghz->ignore_filter, SubGhzProtocolFlag_Magelan); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, protocol_ignore_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); } // Enable speaker, will send all incoming noises and signals to speaker so you can listen how your remote sounds like :) item = variable_item_list_add( subghz->variable_item_list, "Sound:", - SPEAKER_COUNT, + COMBO_BOX_COUNT, subghz_scene_receiver_config_set_speaker, subghz); value_index = value_index_uint32( - subghz_txrx_speaker_get_state(subghz->txrx), speaker_value, SPEAKER_COUNT); + subghz_txrx_speaker_get_state(subghz->txrx), speaker_value, COMBO_BOX_COUNT); variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, speaker_text[value_index]); + variable_item_set_current_value_text(item, combobox_text[value_index]); + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != + SubGhzCustomEventManagerSet) { + // Reset to default + variable_item_list_add(subghz->variable_item_list, "Reset to default", 1, NULL, NULL); + + variable_item_list_set_enter_callback( + subghz->variable_item_list, + subghz_scene_receiver_config_var_list_enter_callback, + subghz); + } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerSet) { // Lock keyboard @@ -412,6 +460,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_var_list_enter_callback, subghz); } + if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubGhzCustomEventManagerSet) { item = variable_item_list_add( @@ -439,6 +488,9 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even subghz_lock(subghz); scene_manager_previous_scene(subghz->scene_manager); consumed = true; + } else if(event.event == SubGhzCustomEventSceneSettingResetToDefault) { + scene_manager_previous_scene(subghz->scene_manager); + consumed = true; } } return consumed; @@ -448,6 +500,9 @@ void subghz_scene_receiver_config_on_exit(void* context) { SubGhz* subghz = context; variable_item_list_set_selected_item(subghz->variable_item_list, 0); variable_item_list_reset(subghz->variable_item_list); +#ifdef FURI_DEBUG + subghz_last_settings_log(subghz->last_settings); +#endif subghz_last_settings_save(subghz->last_settings); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index d77d93b90..cd4f0f836 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -1,8 +1,9 @@ #include "../subghz_i.h" -#include "../helpers/subghz_custom_event.h" #include +#define TAG "SubGhzSceneReceiverInfo" + void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); SubGhz* subghz = context; diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c index 6a5346492..276e5ecc0 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_success.c +++ b/applications/main/subghz/scenes/subghz_scene_save_success.c @@ -42,7 +42,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart); subghz->idx_menu_chosen = 0; - subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz); + subghz_txrx_set_rx_callback(subghz->txrx, NULL, subghz); if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); diff --git a/applications/main/subghz/scenes/subghz_scene_saved.c b/applications/main/subghz/scenes/subghz_scene_saved.c index 8b198e339..af4c35835 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved.c +++ b/applications/main/subghz/scenes/subghz_scene_saved.c @@ -1,5 +1,7 @@ #include "../subghz_i.h" +#define TAG "SubGhzSceneSaved" + void subghz_scene_saved_on_enter(void* context) { SubGhz* subghz = context; diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index bb51c073d..07c7b6041 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -4,6 +4,8 @@ #include +#define TAG "SubGhzSceneTransmitter" + void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 2af334db6..b5e6371e9 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -1,9 +1,10 @@ /* Abandon hope, all ye who enter here. */ +#include #include #include +#include #include "subghz_i.h" -#include #define TAG "SubGhzApp" @@ -73,7 +74,7 @@ static void subghz_load_custom_presets(SubGhzSetting* setting) { FlipperFormat* fff_temp = flipper_format_string_alloc(); - for(uint8_t i = 0; i < COUNT_OF(presets); i++) { + for(size_t i = 0; i < COUNT_OF(presets); i++) { flipper_format_insert_or_update_string_cstr(fff_temp, "Custom_preset_data", presets[i][1]); flipper_format_rewind(fff_temp); @@ -111,7 +112,9 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { // Open Notification record subghz->notifications = furi_record_open(RECORD_NOTIFICATION); - +#if SUBGHZ_MEASURE_LOADING + uint32_t load_ticks = furi_get_tick(); +#endif subghz->txrx = subghz_txrx_alloc(); if(!alloc_for_tx_only) { @@ -195,35 +198,46 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { // Load last used values for Read, Read RAW, etc. or default subghz->last_settings = subghz_last_settings_alloc(); - subghz_last_settings_load(subghz->last_settings, 0); - if(!alloc_for_tx_only) { -#if FURI_DEBUG - FURI_LOG_D( - TAG, - "last frequency: %ld, preset: %ld", - subghz->last_settings->frequency, - subghz->last_settings->preset); + size_t preset_count = subghz_setting_get_preset_count(setting); + subghz_last_settings_load(subghz->last_settings, preset_count); +#ifdef FURI_DEBUG + subghz_last_settings_log(subghz->last_settings); #endif - subghz_setting_set_default_frequency(setting, subghz->last_settings->frequency); - } - if(!alloc_for_tx_only) { - subghz_txrx_set_preset(subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0); +#if SUBGHZ_LAST_SETTING_SAVE_PRESET + subghz_txrx_set_preset_internal( + subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index); +#else + subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency); +#endif + subghz->history = subghz_history_alloc(); } subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); - if(!alloc_for_tx_only) { - subghz->history = subghz_history_alloc(); - } - subghz->secure_data = malloc(sizeof(SecureData)); - subghz->filter = SubGhzProtocolFlag_Decodable; - subghz->ignore_filter = 0x0; + if(!alloc_for_tx_only) { + subghz->ignore_filter = subghz->last_settings->ignore_filter; + subghz->filter = subghz->last_settings->filter; + } else { + subghz->filter = SubGhzProtocolFlag_Decodable; + subghz->ignore_filter = 0x0; + } subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz); + if(!alloc_for_tx_only) { + if(!float_is_equal(subghz->last_settings->rssi, 0)) { + subghz_threshold_rssi_set(subghz->threshold_rssi, subghz->last_settings->rssi); + } else { + subghz->last_settings->rssi = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; + } + } +#if SUBGHZ_MEASURE_LOADING + load_ticks = furi_get_tick() - load_ticks; + FURI_LOG_I(TAG, "Loaded: %ld ms.", load_ticks); +#endif //Init Error_str subghz->error_str = furi_string_alloc(); diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 5640ca25d..3af85750a 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -4,30 +4,13 @@ #include "subghz/types.h" #include #include -#include -#include -#include #include #include #include -#include "views/receiver.h" - #include -#include -#include #define TAG "SubGhz" -void subghz_set_default_preset(SubGhz* subghz) { - furi_assert(subghz); - subghz_txrx_set_preset( - subghz->txrx, - "AM650", - subghz_setting_get_default_frequency(subghz_txrx_get_setting(subghz->txrx)), - NULL, - 0); -} - void subghz_blink_start(SubGhz* subghz) { furi_assert(subghz); notification_message(subghz->notifications, &sequence_blink_stop); @@ -60,7 +43,7 @@ void subghz_dialog_message_freq_error(SubGhz* subghz, bool only_rx) { DialogsApp* dialogs = subghz->dialogs; DialogMessage* message = dialog_message_alloc(); const char* header_text = "Frequency not supported"; - const char* message_text = "Frequency\nis outside of\nsuported range."; + const char* message_text = "Frequency\nis outside of\nsupported range."; if(only_rx) { header_text = "Transmission is blocked"; @@ -124,6 +107,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { // TODO: use different frequency allowed lists for differnet modules (non cc1101) if(!furi_hal_subghz_is_tx_allowed(temp_data32)) { FURI_LOG_E(TAG, "This frequency can only be used for RX"); + load_key_state = SubGhzLoadKeyStateOnlyRx; break; } diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 6a266bf51..4297699db 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -42,6 +42,8 @@ #define SUBGHZ_MAX_LEN_NAME 64 #define SUBGHZ_EXT_PRESET_NAME true +#define SUBGHZ_RAW_THRESHOLD_MIN (-90.0f) +#define SUBGHZ_MEASURE_LOADING false typedef struct { uint8_t fix[4]; @@ -98,7 +100,6 @@ struct SubGhz { void* rpc_ctx; }; -void subghz_set_default_preset(SubGhz* subghz); void subghz_blink_start(SubGhz* subghz); void subghz_blink_stop(SubGhz* subghz); diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 465312b19..89a3eac68 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -6,21 +6,19 @@ #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_VERSION 1 #define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/last_subghz.settings") -// 1 = "AM650" -// "AM270", "AM650", "FM238", "FM476", -#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 -#define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 -#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2 -#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER -93.0f #define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency" -//#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset" +#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset" // AKA Modulation #define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL "FeedbackLevel" #define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_ENABLED "External" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER "ExtPower" #define SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES "TimestampNames" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER_AMP "ExtPowerAmp" +#define SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE "Hopping" +#define SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER "IgnoreFilter" +#define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter" +#define SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD "RSSI" SubGhzLastSettings* subghz_last_settings_alloc(void) { SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); @@ -33,11 +31,7 @@ void subghz_last_settings_free(SubGhzLastSettings* instance) { } void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) { - UNUSED(preset_count); furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "subghz_last_settings_load"); -#endif Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); @@ -49,15 +43,23 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count bool temp_external_module_power_5v_disable = false; bool temp_external_module_power_amp = false; bool temp_timestamp_file_names = false; - //int32_t temp_preset = 0; + bool temp_enable_hopping = false; + uint32_t temp_ignore_filter = 0; + uint32_t temp_filter = 0; + float temp_rssi = 0; + uint32_t temp_preset = 0; + + bool preset_was_read = false; + bool rssi_was_read = false; + bool filter_was_read = false; + bool ignore_filter_was_read = false; bool frequency_analyzer_feedback_level_was_read = false; bool frequency_analyzer_trigger_was_read = false; if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH && flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) { - /* - flipper_format_read_int32( - fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (int32_t*)&temp_preset, 1);*/ + preset_was_read = flipper_format_read_uint32( + fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (uint32_t*)&temp_preset, 1); flipper_format_read_uint32( fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1); frequency_analyzer_feedback_level_was_read = flipper_format_read_uint32( @@ -90,22 +92,40 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER_AMP, (bool*)&temp_external_module_power_amp, 1); - + flipper_format_read_bool( + fff_data_file, + SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, + (bool*)&temp_enable_hopping, + 1); + rssi_was_read = flipper_format_read_float( + fff_data_file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, (float*)&temp_rssi, 1); + ignore_filter_was_read = flipper_format_read_uint32( + fff_data_file, + SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER, + (uint32_t*)&temp_ignore_filter, + 1); + filter_was_read = flipper_format_read_uint32( + fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FILTER, (uint32_t*)&temp_filter, 1); } else { FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH); } if(temp_frequency == 0 || !furi_hal_subghz_is_tx_allowed(temp_frequency)) { FURI_LOG_W(TAG, "Last used frequency not found or can't be used!"); + instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY; - instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; instance->frequency_analyzer_feedback_level = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL; instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; instance->external_module_enabled = false; instance->timestamp_file_names = false; instance->external_module_power_amp = false; - + instance->enable_hopping = false; + instance->ignore_filter = 0x00; + // See bin_raw_value in applications/main/subghz/scenes/subghz_scene_receiver_config.c + instance->filter = SubGhzProtocolFlag_Decodable; + instance->rssi = SUBGHZ_RAW_THRESHOLD_MIN; } else { instance->frequency = temp_frequency; instance->frequency_analyzer_feedback_level = @@ -117,10 +137,19 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count temp_frequency_analyzer_trigger : SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; - /*if(temp_preset > (int32_t)preset_count - 1 || temp_preset < 0) { - FURI_LOG_W(TAG, "Last used preset no found");*/ - instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; - + if(!preset_was_read) { + FURI_LOG_W(TAG, "Preset was not read. Set default"); + instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + } else if(temp_preset > (uint32_t)preset_count - 1) { + FURI_LOG_W( + TAG, + "Last used preset out of range. Preset to set: %ld, Max index: %ld. Set default", + temp_preset, + (uint32_t)preset_count - 1); + instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; + } else { + instance->preset_index = temp_preset; + } instance->external_module_enabled = temp_external_module_enabled; instance->external_module_power_5v_disable = temp_external_module_power_5v_disable; @@ -130,12 +159,22 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count // External power amp CC1101 instance->external_module_power_amp = temp_external_module_power_amp; + instance->rssi = rssi_was_read ? temp_rssi : SUBGHZ_RAW_THRESHOLD_MIN; + instance->enable_hopping = temp_enable_hopping; + instance->ignore_filter = ignore_filter_was_read ? temp_ignore_filter : 0x00; +#if SUBGHZ_LAST_SETTING_SAVE_BIN_RAW + instance->filter = filter_was_read ? temp_filter : SubGhzProtocolFlag_Decodable; +#else + if(filter_was_read) { + instance->filter = temp_filter != SubGhzProtocolFlag_Decodable ? + SubGhzProtocolFlag_Decodable : + temp_filter; + } else { + instance->filter = SubGhzProtocolFlag_Decodable; + } +#endif // Set globally in furi hal furi_hal_subghz_set_ext_power_amp(instance->external_module_power_amp); - - /*/} else { - instance->preset = temp_preset; - }*/ } flipper_format_file_close(fff_data_file); @@ -145,10 +184,10 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count bool subghz_last_settings_save(SubGhzLastSettings* instance) { furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "last_settings_save"); -#endif +#if SUBGHZ_LAST_SETTING_SAVE_BIN_RAW != true + instance->filter = SubGhzProtocolFlag_Decodable; +#endif bool saved = false; Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); @@ -165,12 +204,10 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { if(!flipper_format_write_header_cstr( file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION)) break; - - /* - if(!flipper_format_insert_or_update_int32( - file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset, 1)) { + if(!flipper_format_insert_or_update_uint32( + file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset_index, 1)) { break; - }*/ + } if(!flipper_format_insert_or_update_uint32( file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) { break; @@ -217,6 +254,22 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { 1)) { break; } + if(!flipper_format_insert_or_update_bool( + file, SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, &instance->enable_hopping, 1)) { + break; + } + if(!flipper_format_insert_or_update_float( + file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, &instance->rssi, 1)) { + break; + } + if(!flipper_format_insert_or_update_uint32( + file, SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER, &instance->ignore_filter, 1)) { + break; + } + if(!flipper_format_insert_or_update_uint32( + file, SUBGHZ_LAST_SETTING_FIELD_FILTER, &instance->filter, 1)) { + break; + } saved = true; } while(0); @@ -230,3 +283,43 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { return saved; } + +const char* LOG_ON = "ON"; +const char* LOG_OFF = "OFF"; + +static inline const char* + subghz_last_settings_log_filter_get_index(uint32_t filter, uint32_t flag) { + return READ_BIT(filter, flag) > 0 ? LOG_ON : LOG_OFF; +} + +static inline const char* bool_to_char(bool value) { + return value ? LOG_ON : LOG_OFF; +} + +void subghz_last_settings_log(SubGhzLastSettings* instance) { + furi_assert(instance); + + FURI_LOG_I( + TAG, + "Frequency: %03ld.%02ld, FeedbackLevel: %ld, FATrigger: %.2f, External: %s, ExtPower: %s, TimestampNames: %s, ExtPowerAmp: %s,\n" + "Hopping: %s,\nPreset: %ld, RSSI: %.2f, " + "Starline: %s, Cars: %s, Magellan: %s, BinRAW: %s", + instance->frequency / 1000000 % 1000, + instance->frequency / 10000 % 100, + instance->frequency_analyzer_feedback_level, + (double)instance->frequency_analyzer_trigger, + bool_to_char(instance->external_module_enabled), + bool_to_char(instance->external_module_power_5v_disable), + bool_to_char(instance->timestamp_file_names), + bool_to_char(instance->external_module_power_amp), + bool_to_char(instance->enable_hopping), + instance->preset_index, + (double)instance->rssi, + subghz_last_settings_log_filter_get_index( + instance->ignore_filter, SubGhzProtocolFlag_StarLine), + subghz_last_settings_log_filter_get_index( + instance->ignore_filter, SubGhzProtocolFlag_AutoAlarms), + subghz_last_settings_log_filter_get_index( + instance->ignore_filter, SubGhzProtocolFlag_Magelan), + subghz_last_settings_log_filter_get_index(instance->filter, SubGhzProtocolFlag_BinRAW)); +} diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h index c351cb6a5..b3742d4bf 100644 --- a/applications/main/subghz/subghz_last_settings.h +++ b/applications/main/subghz/subghz_last_settings.h @@ -4,10 +4,20 @@ #include #include #include +#include + +#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER (-93.0f) +#define SUBGHZ_LAST_SETTING_SAVE_BIN_RAW true +#define SUBGHZ_LAST_SETTING_SAVE_PRESET true +// 1 = "AM650" +// "AM270", "AM650", "FM238", "FM476", +#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 +#define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 +#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2 typedef struct { uint32_t frequency; - int32_t preset; + uint32_t preset_index; // AKA Modulation uint32_t frequency_analyzer_feedback_level; float frequency_analyzer_trigger; // TODO not using but saved so as not to change the version @@ -16,6 +26,10 @@ typedef struct { bool external_module_power_amp; // saved so as not to change the version bool timestamp_file_names; + bool enable_hopping; + uint32_t ignore_filter; + uint32_t filter; + float rssi; } SubGhzLastSettings; SubGhzLastSettings* subghz_last_settings_alloc(void); @@ -25,3 +39,5 @@ void subghz_last_settings_free(SubGhzLastSettings* instance); void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count); bool subghz_last_settings_save(SubGhzLastSettings* instance); + +void subghz_last_settings_log(SubGhzLastSettings* instance); diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 9d514b8ca..010e47062 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -12,7 +12,7 @@ #define MENU_ITEMS 4u #define UNLOCK_CNT 3 -#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f +// #define SUBGHZ_RAW_THRESHOLD_MIN (-90.0f) #define FLIP_TIMEOUT (500) @@ -62,6 +62,8 @@ typedef struct { FuriString* preset_str; FuriString* history_stat_str; FuriString* progress_str; + bool hopping_enabled; + bool bin_raw_enabled; SubGhzReceiverHistory* history; uint16_t idx; uint16_t list_offset; @@ -200,7 +202,9 @@ void subghz_view_receiver_add_data_statusbar( SubGhzViewReceiver* subghz_receiver, const char* frequency_str, const char* preset_str, - const char* history_stat_str) { + const char* history_stat_str, + bool hopping_enabled, + bool bin_raw_enabled) { furi_assert(subghz_receiver); with_view_model( subghz_receiver->view, @@ -209,6 +213,8 @@ void subghz_view_receiver_add_data_statusbar( furi_string_set(model->frequency_str, frequency_str); furi_string_set(model->preset_str, preset_str); furi_string_set(model->history_stat_str, history_stat_str); + model->hopping_enabled = hopping_enabled; + model->bin_raw_enabled = bin_raw_enabled; }, true); } @@ -311,7 +317,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_set_color(canvas, ColorBlack); if(model->history_item == 0) { - // TODO if(model->mode == SubGhzViewReceiverModeLive) { canvas_draw_icon( canvas, @@ -320,9 +325,19 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { (model->device_type == SubGhzRadioDeviceTypeInternal) ? &I_Scanning_123x52 : &I_Fishing_123x52); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 63, 46, "Scanning..."); + if(model->hopping_enabled) { + canvas_draw_str(canvas, 59, 46, "Hopper scan..."); + } else { + canvas_draw_str(canvas, 59, 46, "Fixed scan..."); + } //canvas_draw_line(canvas, 46, 51, 125, 51); canvas_set_font(canvas, FontSecondary); + + if(model->bin_raw_enabled) { + const uint8_t vertical_offset = 17; + const uint8_t horizontal_offset = 118; + canvas_draw_icon(canvas, horizontal_offset, vertical_offset, &I_Cos_9x7); + } } else { canvas_draw_icon( canvas, @@ -458,8 +473,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { return true; } + bool consumed = false; if(event->key == InputKeyBack && event->type == InputTypeShort) { subghz_receiver->callback(SubGhzCustomEventViewReceiverBack, subghz_receiver->context); + consumed = true; } else if( event->key == InputKeyUp && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { @@ -471,6 +488,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { subghz_view_receiver_show_time_moment(context); }, true); + consumed = true; } else if( event->key == InputKeyDown && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { @@ -484,8 +502,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { } }, true); + consumed = true; } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { subghz_receiver->callback(SubGhzCustomEventViewReceiverConfig, subghz_receiver->context); + consumed = true; } else if(event->key == InputKeyRight && event->type == InputTypeLong) { with_view_model( subghz_receiver->view, @@ -498,6 +518,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { } }, false); + consumed = true; } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( subghz_receiver->view, @@ -509,11 +530,13 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { } }, false); + consumed = true; } - subghz_view_receiver_update_offset(subghz_receiver); - - return true; + if(consumed) { + subghz_view_receiver_update_offset(subghz_receiver); + } + return consumed; } void subghz_view_receiver_enter(void* context) { @@ -543,6 +566,8 @@ void subghz_view_receiver_exit(void* context) { model->list_offset = 0; model->history_item = 0; model->nodraw = false; + model->hopping_enabled = false; + model->bin_raw_enabled = false; }, false); furi_timer_stop(subghz_receiver->timer); @@ -579,6 +604,8 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { model->bar_show = SubGhzViewReceiverBarShowDefault; model->nodraw = false; model->history = malloc(sizeof(SubGhzReceiverHistory)); + model->hopping_enabled = false; + model->bin_raw_enabled = false; SubGhzReceiverMenuItemArray_init(model->history->data); }, true); @@ -622,7 +649,7 @@ View* subghz_view_receiver_get_view(SubGhzViewReceiver* subghz_receiver) { uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver) { furi_assert(subghz_receiver); - uint16_t idx = 0; + uint16_t idx; with_view_model( subghz_receiver->view, SubGhzViewReceiverModel * model, { idx = model->idx; }, false); return idx; diff --git a/applications/main/subghz/views/receiver.h b/applications/main/subghz/views/receiver.h index 57718cfc4..c280e1de6 100644 --- a/applications/main/subghz/views/receiver.h +++ b/applications/main/subghz/views/receiver.h @@ -31,7 +31,9 @@ void subghz_view_receiver_add_data_statusbar( SubGhzViewReceiver* subghz_receiver, const char* frequency_str, const char* preset_str, - const char* history_stat_str); + const char* history_stat_str, + bool hopping_enabled, + bool bin_raw_enabled); void subghz_view_receiver_set_radio_device_type( SubGhzViewReceiver* subghz_receiver, diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.h b/applications/main/subghz/views/subghz_frequency_analyzer.h index f8c643222..d304cc795 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.h +++ b/applications/main/subghz/views/subghz_frequency_analyzer.h @@ -32,4 +32,4 @@ SubGHzFrequencyAnalyzerFeedbackLevel subghz_frequency_analyzer_feedback_level( SubGHzFrequencyAnalyzerFeedbackLevel level, bool update); -float subghz_frequency_analyzer_get_trigger_level(SubGhzFrequencyAnalyzer* instance); \ No newline at end of file +float subghz_frequency_analyzer_get_trigger_level(SubGhzFrequencyAnalyzer* instance); diff --git a/applications/main/subghz/views/subghz_read_raw.h b/applications/main/subghz/views/subghz_read_raw.h index c7d87f2d5..54eea1440 100644 --- a/applications/main/subghz/views/subghz_read_raw.h +++ b/applications/main/subghz/views/subghz_read_raw.h @@ -4,8 +4,6 @@ #include "../helpers/subghz_types.h" #include "../helpers/subghz_custom_event.h" -#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f - typedef struct SubGhzReadRAW SubGhzReadRAW; typedef void (*SubGhzReadRAWCallback)(SubGhzCustomEvent event, void* context); diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index 58dfb9300..2c40fdc16 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -473,6 +473,7 @@ void cli_commands_init(Cli* cli) { cli_add_command(cli, "uptime", CliCommandFlagDefault, cli_command_uptime, NULL); cli_add_command(cli, "date", CliCommandFlagParallelSafe, cli_command_date, NULL); cli_add_command(cli, "log", CliCommandFlagParallelSafe, cli_command_log, NULL); + cli_add_command(cli, "l", CliCommandFlagParallelSafe, cli_command_log, NULL); cli_add_command(cli, "sysctl", CliCommandFlagDefault, cli_command_sysctl, NULL); cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL); cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL); diff --git a/assets/icons/SubGhz/Cos_9x7.png b/assets/icons/SubGhz/Cos_9x7.png new file mode 100644 index 000000000..599ec0e58 Binary files /dev/null and b/assets/icons/SubGhz/Cos_9x7.png differ