Просмотр исходного кода

SubGhz: support 310 MHz and fix (#1262)

* SubGhz: add frequency support 310 MHz
* SubGhz: deleting a TMP file using the "Erase" button in Read RAW
* SubGhz: fix frequency analyzer scan speed
* SubGhz: fix start duration came_atomo protocol
* SubGhz: refactoring subghz_setting
* SubGhz: refactoring load setting frequency analyzer
* SubGhz: fix load setting,  default frequency
* SubGhz: patch raw temp file remove code to work with string_t
* Storage: parallel safe cli
* SubGhz: new frequency settings loading system
* Assets: recompile to include latest subghz custom frequency control changes

Co-authored-by: あく <alleteam@gmail.com>
Skorpionm 3 лет назад
Родитель
Сommit
66dbb68947

+ 1 - 1
applications/storage/storage_cli.c

@@ -593,7 +593,7 @@ static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) {
 void storage_on_system_start() {
 void storage_on_system_start() {
 #ifdef SRV_CLI
 #ifdef SRV_CLI
     Cli* cli = furi_record_open("cli");
     Cli* cli = furi_record_open("cli");
-    cli_add_command(cli, "storage", CliCommandFlagDefault, storage_cli, NULL);
+    cli_add_command(cli, "storage", CliCommandFlagParallelSafe, storage_cli, NULL);
     cli_add_command(
     cli_add_command(
         cli, "factory_reset", CliCommandFlagParallelSafe, storage_cli_factory_reset, NULL);
         cli, "factory_reset", CliCommandFlagParallelSafe, storage_cli_factory_reset, NULL);
     furi_record_close("cli");
     furi_record_close("cli");

+ 10 - 9
applications/subghz/helpers/subghz_frequency_analyzer_worker.c

@@ -3,8 +3,6 @@
 
 
 #include <furi.h>
 #include <furi.h>
 
 
-#include "../subghz_i.h"
-
 #define TAG "SubghzFrequencyAnalyzerWorker"
 #define TAG "SubghzFrequencyAnalyzerWorker"
 
 
 #define SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD -95.0f
 #define SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD -95.0f
@@ -82,7 +80,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
     cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz);
     cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz);
     cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW);
     cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW);
     cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_MDMCFG3,
     cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_MDMCFG3,
-                     0b11111111); // symbol rate
+                     0b01111111); // symbol rate
     cc1101_write_reg(
     cc1101_write_reg(
         &furi_hal_spi_bus_handle_subghz,
         &furi_hal_spi_bus_handle_subghz,
         CC1101_AGCCTRL2,
         CC1101_AGCCTRL2,
@@ -130,7 +128,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
                 furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
                 furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
 
 
                 // delay will be in range between 1 and 2ms
                 // delay will be in range between 1 and 2ms
-                osDelay(2);
+                osDelay(3);
 
 
                 rssi = furi_hal_subghz_get_rssi();
                 rssi = furi_hal_subghz_get_rssi();
 
 
@@ -179,9 +177,12 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
                     furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
                     furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
 
 
                     // delay will be in range between 1 and 2ms
                     // delay will be in range between 1 and 2ms
-                    osDelay(2);
+                    osDelay(3);
 
 
                     rssi = furi_hal_subghz_get_rssi();
                     rssi = furi_hal_subghz_get_rssi();
+
+                    FURI_LOG_T(TAG, "#:%u:%f", frequency, (double)rssi);
+
                     if(frequency_rssi.rssi < rssi) {
                     if(frequency_rssi.rssi < rssi) {
                         frequency_rssi.rssi = rssi;
                         frequency_rssi.rssi = rssi;
                         frequency_rssi.frequency = frequency;
                         frequency_rssi.frequency = frequency;
@@ -222,7 +223,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
     return 0;
     return 0;
 }
 }
 
 
-SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc() {
+SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc(void* context) {
+    furi_assert(context);
     SubGhzFrequencyAnalyzerWorker* instance = malloc(sizeof(SubGhzFrequencyAnalyzerWorker));
     SubGhzFrequencyAnalyzerWorker* instance = malloc(sizeof(SubGhzFrequencyAnalyzerWorker));
 
 
     instance->thread = furi_thread_alloc();
     instance->thread = furi_thread_alloc();
@@ -231,8 +233,8 @@ SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc() {
     furi_thread_set_context(instance->thread, instance);
     furi_thread_set_context(instance->thread, instance);
     furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread);
     furi_thread_set_callback(instance->thread, subghz_frequency_analyzer_worker_thread);
 
 
-    instance->setting = subghz_setting_alloc();
-    subghz_setting_load(instance->setting, "/ext/subghz/assets/setting_frequency_analyzer_user");
+    SubGhz* subghz = context;
+    instance->setting = subghz->setting;
     return instance;
     return instance;
 }
 }
 
 
@@ -240,7 +242,6 @@ void subghz_frequency_analyzer_worker_free(SubGhzFrequencyAnalyzerWorker* instan
     furi_assert(instance);
     furi_assert(instance);
 
 
     furi_thread_free(instance->thread);
     furi_thread_free(instance->thread);
-    subghz_setting_free(instance->setting);
     free(instance);
     free(instance);
 }
 }
 
 

+ 3 - 1
applications/subghz/helpers/subghz_frequency_analyzer_worker.h

@@ -1,6 +1,7 @@
 #pragma once
 #pragma once
 
 
 #include <furi_hal.h>
 #include <furi_hal.h>
+#include "../subghz_i.h"
 
 
 typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker;
 typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker;
 
 
@@ -14,9 +15,10 @@ typedef struct {
 
 
 /** Allocate SubGhzFrequencyAnalyzerWorker
 /** Allocate SubGhzFrequencyAnalyzerWorker
  * 
  * 
+ * @param context SubGhz* context
  * @return SubGhzFrequencyAnalyzerWorker* 
  * @return SubGhzFrequencyAnalyzerWorker* 
  */
  */
-SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc();
+SubGhzFrequencyAnalyzerWorker* subghz_frequency_analyzer_worker_alloc(void* context);
 
 
 /** Free SubGhzFrequencyAnalyzerWorker
 /** Free SubGhzFrequencyAnalyzerWorker
  * 
  * 

+ 2 - 1
applications/subghz/helpers/subghz_testing.c

@@ -4,6 +4,7 @@ const uint32_t subghz_frequencies_testing[] = {
     /* 300 - 348 */
     /* 300 - 348 */
     300000000,
     300000000,
     304500000,
     304500000,
+    310000000,
     312025000,
     312025000,
     313250000,
     313250000,
     313625000,
     313625000,
@@ -34,4 +35,4 @@ const uint32_t subghz_frequencies_testing[] = {
 
 
 const uint32_t subghz_frequencies_count_testing =
 const uint32_t subghz_frequencies_count_testing =
     sizeof(subghz_frequencies_testing) / sizeof(uint32_t);
     sizeof(subghz_frequencies_testing) / sizeof(uint32_t);
-const uint32_t subghz_frequencies_433_92_testing = 12;
+const uint32_t subghz_frequencies_433_92_testing = 13;

+ 4 - 0
applications/subghz/scenes/subghz_scene_read_raw.c

@@ -168,6 +168,10 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
 
 
         case SubGhzCustomEventViewReadRAWErase:
         case SubGhzCustomEventViewReadRAWErase:
             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
             subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
+            if(subghz_scene_read_raw_update_filename(subghz)) {
+                string_set(subghz->file_path_tmp, subghz->file_path);
+                subghz_delete_file(subghz);
+            }
             notification_message(subghz->notifications, &sequence_reset_rgb);
             notification_message(subghz->notifications, &sequence_reset_rgb);
             return true;
             return true;
             break;
             break;

+ 129 - 121
applications/subghz/subghz_setting.c

@@ -7,20 +7,19 @@
 
 
 #define TAG "SubGhzSetting"
 #define TAG "SubGhzSetting"
 
 
-#define SUBGHZ_SETTING_FILE_VERSION 1
 #define SUBGHZ_SETTING_FILE_TYPE "Flipper SubGhz Setting File"
 #define SUBGHZ_SETTING_FILE_TYPE "Flipper SubGhz Setting File"
+#define SUBGHZ_SETTING_FILE_VERSION 1
 
 
-typedef enum {
-    SubGhzSettingStateNoLoad = 0,
-    SubGhzSettingStateLoadFrequencyDefault,
-    SubGhzSettingStateOkLoad,
-} SubGhzSettingState;
+#define FREQUENCY_FLAG_DEFAULT (1 << 31)
+#define FREQUENCY_MASK (0xFFFFFFFF ^ FREQUENCY_FLAG_DEFAULT)
 
 
-static const uint32_t subghz_frequencies[] = {
+/* Default */
+static const uint32_t subghz_frequency_list[] = {
     /* 300 - 348 */
     /* 300 - 348 */
     300000000,
     300000000,
     303875000,
     303875000,
     304250000,
     304250000,
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
 
 
@@ -29,7 +28,7 @@ static const uint32_t subghz_frequencies[] = {
     418000000,
     418000000,
     433075000, /* LPD433 first */
     433075000, /* LPD433 first */
     433420000,
     433420000,
-    433920000, /* LPD433 mid */
+    433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
     434420000,
     434420000,
     434775000, /* LPD433 last channels */
     434775000, /* LPD433 last channels */
     438900000,
     438900000,
@@ -40,7 +39,9 @@ static const uint32_t subghz_frequencies[] = {
     925000000,
     925000000,
     0,
     0,
 };
 };
-static const uint32_t subghz_hopper_frequencies[] = {
+
+static const uint32_t subghz_hopper_frequency_list[] = {
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
     390000000,
     390000000,
@@ -48,13 +49,14 @@ static const uint32_t subghz_hopper_frequencies[] = {
     868350000,
     868350000,
     0,
     0,
 };
 };
-static const uint32_t subghz_frequency_default_index = 9;
 
 
-static const uint32_t subghz_frequencies_region_eu_ru[] = {
+/* Europe and Russia */
+static const uint32_t subghz_frequency_list_region_eu_ru[] = {
     /* 300 - 348 */
     /* 300 - 348 */
     300000000,
     300000000,
     303875000,
     303875000,
     304250000,
     304250000,
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
 
 
@@ -63,7 +65,7 @@ static const uint32_t subghz_frequencies_region_eu_ru[] = {
     418000000,
     418000000,
     433075000, /* LPD433 first */
     433075000, /* LPD433 first */
     433420000,
     433420000,
-    433920000, /* LPD433 mid */
+    433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
     434420000,
     434420000,
     434775000, /* LPD433 last channels */
     434775000, /* LPD433 last channels */
     438900000,
     438900000,
@@ -74,7 +76,8 @@ static const uint32_t subghz_frequencies_region_eu_ru[] = {
     925000000,
     925000000,
     0,
     0,
 };
 };
-static const uint32_t subghz_hopper_frequencies_region_eu_ru[] = {
+static const uint32_t subghz_hopper_frequency_list_region_eu_ru[] = {
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
     390000000,
     390000000,
@@ -82,13 +85,14 @@ static const uint32_t subghz_hopper_frequencies_region_eu_ru[] = {
     868350000,
     868350000,
     0,
     0,
 };
 };
-static const uint32_t subghz_frequency_default_index_region_eu_ru = 9;
 
 
-static const uint32_t subghz_frequencies_region_us_ca_au[] = {
+/* Region 0 */
+static const uint32_t subghz_frequency_list_region_us_ca_au[] = {
     /* 300 - 348 */
     /* 300 - 348 */
     300000000,
     300000000,
     303875000,
     303875000,
     304250000,
     304250000,
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
 
 
@@ -97,7 +101,7 @@ static const uint32_t subghz_frequencies_region_us_ca_au[] = {
     418000000,
     418000000,
     433075000, /* LPD433 first */
     433075000, /* LPD433 first */
     433420000,
     433420000,
-    433920000, /* LPD433 mid */
+    433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
     434420000,
     434420000,
     434775000, /* LPD433 last channels */
     434775000, /* LPD433 last channels */
     438900000,
     438900000,
@@ -108,7 +112,8 @@ static const uint32_t subghz_frequencies_region_us_ca_au[] = {
     925000000,
     925000000,
     0,
     0,
 };
 };
-static const uint32_t subghz_hopper_frequencies_region_us_ca_au[] = {
+static const uint32_t subghz_hopper_frequency_list_region_us_ca_au[] = {
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
     390000000,
     390000000,
@@ -116,13 +121,13 @@ static const uint32_t subghz_hopper_frequencies_region_us_ca_au[] = {
     868350000,
     868350000,
     0,
     0,
 };
 };
-static const uint32_t subghz_frequency_default_index_region_us_ca_au = 9;
 
 
-static const uint32_t subghz_frequencies_region_jp[] = {
+static const uint32_t subghz_frequency_list_region_jp[] = {
     /* 300 - 348 */
     /* 300 - 348 */
     300000000,
     300000000,
     303875000,
     303875000,
     304250000,
     304250000,
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
 
 
@@ -131,7 +136,7 @@ static const uint32_t subghz_frequencies_region_jp[] = {
     418000000,
     418000000,
     433075000, /* LPD433 first */
     433075000, /* LPD433 first */
     433420000,
     433420000,
-    433920000, /* LPD433 mid */
+    433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
     434420000,
     434420000,
     434775000, /* LPD433 last channels */
     434775000, /* LPD433 last channels */
     438900000,
     438900000,
@@ -142,7 +147,8 @@ static const uint32_t subghz_frequencies_region_jp[] = {
     925000000,
     925000000,
     0,
     0,
 };
 };
-static const uint32_t subghz_hopper_frequencies_region_jp[] = {
+static const uint32_t subghz_hopper_frequency_list_region_jp[] = {
+    310000000,
     315000000,
     315000000,
     318000000,
     318000000,
     390000000,
     390000000,
@@ -150,72 +156,88 @@ static const uint32_t subghz_hopper_frequencies_region_jp[] = {
     868350000,
     868350000,
     0,
     0,
 };
 };
-static const uint32_t subghz_frequency_default_index_region_jp = 9;
 
 
-LIST_DEF(FrequenciesList, uint32_t)
+LIST_DEF(FrequencyList, uint32_t)
+
+#define M_OPL_FrequencyList_t() LIST_OPLIST(FrequencyList)
 
 
 struct SubGhzSetting {
 struct SubGhzSetting {
-    FrequenciesList_t frequencies;
-    FrequenciesList_t hopper_frequencies;
-    size_t frequencies_count;
-    size_t hopper_frequencies_count;
-    uint32_t frequency_default_index;
+    FrequencyList_t frequencies;
+    FrequencyList_t hopper_frequencies;
 };
 };
 
 
 SubGhzSetting* subghz_setting_alloc(void) {
 SubGhzSetting* subghz_setting_alloc(void) {
     SubGhzSetting* instance = malloc(sizeof(SubGhzSetting));
     SubGhzSetting* instance = malloc(sizeof(SubGhzSetting));
-    FrequenciesList_init(instance->frequencies);
-    FrequenciesList_init(instance->hopper_frequencies);
+    FrequencyList_init(instance->frequencies);
+    FrequencyList_init(instance->hopper_frequencies);
     return instance;
     return instance;
 }
 }
 
 
 void subghz_setting_free(SubGhzSetting* instance) {
 void subghz_setting_free(SubGhzSetting* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    FrequenciesList_clear(instance->frequencies);
-    FrequenciesList_clear(instance->hopper_frequencies);
+    FrequencyList_clear(instance->frequencies);
+    FrequencyList_clear(instance->hopper_frequencies);
     free(instance);
     free(instance);
 }
 }
 
 
-void subghz_setting_load_default(
+static void subghz_setting_load_default_region(
     SubGhzSetting* instance,
     SubGhzSetting* instance,
     const uint32_t frequencies[],
     const uint32_t frequencies[],
-    const uint32_t hopper_frequencies[],
-    const uint32_t frequency_default_index) {
+    const uint32_t hopper_frequencies[]) {
     furi_assert(instance);
     furi_assert(instance);
-    size_t i = 0;
-    FrequenciesList_clear(instance->frequencies);
-    FrequenciesList_clear(instance->hopper_frequencies);
-    i = 0;
-    while(frequencies[i]) {
-        FrequenciesList_push_back(instance->frequencies, frequencies[i]);
-        i++;
+
+    FrequencyList_reset(instance->frequencies);
+    FrequencyList_reset(instance->hopper_frequencies);
+
+    while(*frequencies) {
+        FrequencyList_push_back(instance->frequencies, *frequencies);
+        frequencies++;
     }
     }
-    instance->frequencies_count = i;
 
 
-    i = 0;
-    while(hopper_frequencies[i]) {
-        FrequenciesList_push_back(instance->hopper_frequencies, hopper_frequencies[i]);
-        i++;
+    while(*hopper_frequencies) {
+        FrequencyList_push_back(instance->hopper_frequencies, *hopper_frequencies);
+        hopper_frequencies++;
     }
     }
-    instance->hopper_frequencies_count = i;
+}
 
 
-    instance->frequency_default_index = frequency_default_index;
+void subghz_setting_load_default(SubGhzSetting* instance) {
+    switch(furi_hal_version_get_hw_region()) {
+    case FuriHalVersionRegionEuRu:
+        subghz_setting_load_default_region(
+            instance,
+            subghz_frequency_list_region_eu_ru,
+            subghz_hopper_frequency_list_region_eu_ru);
+        break;
+    case FuriHalVersionRegionUsCaAu:
+        subghz_setting_load_default_region(
+            instance,
+            subghz_frequency_list_region_us_ca_au,
+            subghz_hopper_frequency_list_region_us_ca_au);
+        break;
+    case FuriHalVersionRegionJp:
+        subghz_setting_load_default_region(
+            instance, subghz_frequency_list_region_jp, subghz_hopper_frequency_list_region_jp);
+        break;
+
+    default:
+        subghz_setting_load_default_region(
+            instance, subghz_frequency_list, subghz_hopper_frequency_list);
+        break;
+    }
 }
 }
 
 
 void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
 void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
     furi_assert(instance);
     furi_assert(instance);
 
 
-    FrequenciesList_clear(instance->frequencies);
-    FrequenciesList_clear(instance->hopper_frequencies);
-
     Storage* storage = furi_record_open("storage");
     Storage* storage = furi_record_open("storage");
     FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
     FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
 
 
     string_t temp_str;
     string_t temp_str;
     string_init(temp_str);
     string_init(temp_str);
     uint32_t temp_data32;
     uint32_t temp_data32;
-    SubGhzSettingState loading = SubGhzSettingStateNoLoad;
-    uint16_t i = 0;
+    bool temp_bool;
+
+    subghz_setting_load_default(instance);
 
 
     if(file_path) {
     if(file_path) {
         do {
         do {
@@ -236,63 +258,60 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
                 break;
                 break;
             }
             }
 
 
+            // Standard frequencies (optional)
+            temp_bool = true;
+            flipper_format_read_bool(fff_data_file, "add_standard_frequencies", &temp_bool, 1);
+            if(!temp_bool) {
+                FURI_LOG_I(TAG, "Removing standard frequencies");
+                FrequencyList_reset(instance->frequencies);
+                FrequencyList_reset(instance->hopper_frequencies);
+            } else {
+                FURI_LOG_I(TAG, "Keeping standard frequencies");
+            }
+
+            // Load frequencies
             if(!flipper_format_rewind(fff_data_file)) {
             if(!flipper_format_rewind(fff_data_file)) {
                 FURI_LOG_E(TAG, "Rewind error");
                 FURI_LOG_E(TAG, "Rewind error");
                 break;
                 break;
             }
             }
-            i = 0;
             while(flipper_format_read_uint32(
             while(flipper_format_read_uint32(
-                fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) {
+                fff_data_file, "frequency", (uint32_t*)&temp_data32, 1)) {
                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
                     FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
                     FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
-                    FrequenciesList_push_back(instance->frequencies, temp_data32);
-                    i++;
+                    FrequencyList_push_back(instance->frequencies, temp_data32);
                 } else {
                 } else {
                     FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32);
                     FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32);
                 }
                 }
             }
             }
-            instance->frequencies_count = i;
 
 
+            // Load hopper frequencies
             if(!flipper_format_rewind(fff_data_file)) {
             if(!flipper_format_rewind(fff_data_file)) {
                 FURI_LOG_E(TAG, "Rewind error");
                 FURI_LOG_E(TAG, "Rewind error");
                 break;
                 break;
             }
             }
-            i = 0;
             while(flipper_format_read_uint32(
             while(flipper_format_read_uint32(
-                fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) {
+                fff_data_file, "hopper_frequency", (uint32_t*)&temp_data32, 1)) {
                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
                     FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32);
                     FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32);
-                    FrequenciesList_push_back(instance->hopper_frequencies, temp_data32);
-                    i++;
+                    FrequencyList_push_back(instance->hopper_frequencies, temp_data32);
                 } else {
                 } else {
                     FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32);
                     FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32);
                 }
                 }
             }
             }
-            instance->hopper_frequencies_count = i;
 
 
+            // Default frequency (optional)
             if(!flipper_format_rewind(fff_data_file)) {
             if(!flipper_format_rewind(fff_data_file)) {
                 FURI_LOG_E(TAG, "Rewind error");
                 FURI_LOG_E(TAG, "Rewind error");
                 break;
                 break;
             }
             }
-            if(!flipper_format_read_uint32(
-                   fff_data_file, "Frequency_default", (uint32_t*)&temp_data32, 1)) {
-                FURI_LOG_E(TAG, "Frequency default missing");
-                break;
-            }
-
-            for(i = 0; i < instance->frequencies_count; i++) {
-                if(subghz_setting_get_frequency(instance, i) == temp_data32) {
-                    instance->frequency_default_index = i;
-                    FURI_LOG_I(TAG, "Frequency default index %lu", i);
-                    loading = SubGhzSettingStateLoadFrequencyDefault;
-                    break;
-                }
-            }
-
-            if(loading == SubGhzSettingStateLoadFrequencyDefault) {
-                loading = SubGhzSettingStateOkLoad;
-            } else {
-                FURI_LOG_E(TAG, "Frequency default index missing");
+            if(flipper_format_read_uint32(fff_data_file, "default_frequency", &temp_data32, 1)) {
+                for
+                    M_EACH(frequency, instance->frequencies, FrequencyList_t) {
+                        *frequency &= FREQUENCY_MASK;
+                        if(*frequency == temp_data32) {
+                            *frequency |= FREQUENCY_FLAG_DEFAULT;
+                        }
+                    }
             }
             }
         } while(false);
         } while(false);
     }
     }
@@ -301,67 +320,56 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
     flipper_format_free(fff_data_file);
     flipper_format_free(fff_data_file);
     furi_record_close("storage");
     furi_record_close("storage");
 
 
-    if(loading != SubGhzSettingStateOkLoad) {
-        switch(furi_hal_version_get_hw_region()) {
-        case FuriHalVersionRegionEuRu:
-            subghz_setting_load_default(
-                instance,
-                subghz_frequencies_region_eu_ru,
-                subghz_hopper_frequencies_region_eu_ru,
-                subghz_frequency_default_index_region_eu_ru);
-            break;
-        case FuriHalVersionRegionUsCaAu:
-            subghz_setting_load_default(
-                instance,
-                subghz_frequencies_region_us_ca_au,
-                subghz_hopper_frequencies_region_us_ca_au,
-                subghz_frequency_default_index_region_us_ca_au);
-            break;
-        case FuriHalVersionRegionJp:
-            subghz_setting_load_default(
-                instance,
-                subghz_frequencies_region_jp,
-                subghz_hopper_frequencies_region_jp,
-                subghz_frequency_default_index_region_jp);
-            break;
-
-        default:
-            subghz_setting_load_default(
-                instance,
-                subghz_frequencies,
-                subghz_hopper_frequencies,
-                subghz_frequency_default_index);
-            break;
-        }
+    if(!FrequencyList_size(instance->frequencies) ||
+       !FrequencyList_size(instance->hopper_frequencies)) {
+        FURI_LOG_E(TAG, "Error loading user settings, loading default settings");
+        subghz_setting_load_default(instance);
     }
     }
 }
 }
 
 
 size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) {
 size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    return instance->frequencies_count;
+    return FrequencyList_size(instance->frequencies);
 }
 }
 
 
 size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) {
 size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    return instance->hopper_frequencies_count;
+    return FrequencyList_size(instance->hopper_frequencies);
 }
 }
 
 
 uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) {
 uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) {
     furi_assert(instance);
     furi_assert(instance);
-    return *FrequenciesList_get(instance->frequencies, idx);
+    uint32_t* ret = FrequencyList_get(instance->frequencies, idx);
+    if(ret) {
+        return (*ret) & FREQUENCY_MASK;
+    } else {
+        return 0;
+    }
 }
 }
 
 
 uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) {
 uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) {
     furi_assert(instance);
     furi_assert(instance);
-    return *FrequenciesList_get(instance->hopper_frequencies, idx);
+    uint32_t* ret = FrequencyList_get(instance->hopper_frequencies, idx);
+    if(ret) {
+        return *ret;
+    } else {
+        return 0;
+    }
 }
 }
 
 
 uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) {
 uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    return instance->frequency_default_index;
+    for(size_t i = 0; i < FrequencyList_size(instance->frequencies); i++) {
+        uint32_t frequency = *FrequencyList_get(instance->frequencies, i);
+        if(frequency & FREQUENCY_FLAG_DEFAULT) {
+            return i;
+        }
+    }
+    return 0;
 }
 }
 
 
 uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) {
 uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    return *FrequenciesList_get(instance->frequencies, instance->frequency_default_index);
+    return subghz_setting_get_frequency(
+        instance, subghz_setting_get_frequency_default_index(instance));
 }
 }

+ 1 - 1
applications/subghz/views/subghz_frequency_analyzer.c

@@ -111,7 +111,7 @@ void subghz_frequency_analyzer_enter(void* context) {
     SubGhzFrequencyAnalyzer* instance = context;
     SubGhzFrequencyAnalyzer* instance = context;
 
 
     //Start worker
     //Start worker
-    instance->worker = subghz_frequency_analyzer_worker_alloc();
+    instance->worker = subghz_frequency_analyzer_worker_alloc(instance->context);
 
 
     subghz_frequency_analyzer_worker_set_pair_callback(
     subghz_frequency_analyzer_worker_set_pair_callback(
         instance->worker,
         instance->worker,

+ 2 - 3
assets/resources/Manifest

@@ -1,5 +1,5 @@
 V:0
 V:0
-T:1653334495
+T:1654009290
 D:badusb
 D:badusb
 D:dolphin
 D:dolphin
 D:infrared
 D:infrared
@@ -235,8 +235,7 @@ F:dda1ef895b8a25fde57c874feaaef997:650:subghz/assets/came_atomo
 F:610a0ffa2479a874f2060eb2348104c5:2712:subghz/assets/keeloq_mfcodes
 F:610a0ffa2479a874f2060eb2348104c5:2712:subghz/assets/keeloq_mfcodes
 F:9214f9c10463b746a27e82ce0b96e040:465:subghz/assets/keeloq_mfcodes_user
 F:9214f9c10463b746a27e82ce0b96e040:465:subghz/assets/keeloq_mfcodes_user
 F:653bd8d349055a41e1152e557d4a52d3:202:subghz/assets/nice_flor_s
 F:653bd8d349055a41e1152e557d4a52d3:202:subghz/assets/nice_flor_s
-F:00e967e5c558e44a0651bb821d5cf1d0:414:subghz/assets/setting_frequency_analyzer_user
-F:16e8c7cb4a13f26ea55b2b0a59f9cc7a:554:subghz/assets/setting_user
+F:c6ec4374275cd20f482ecd46de9f53e3:528:subghz/assets/setting_user
 D:u2f/assets
 D:u2f/assets
 F:7e11e688e39034bbb9d88410044795e1:365:u2f/assets/cert.der
 F:7e11e688e39034bbb9d88410044795e1:365:u2f/assets/cert.der
 F:f60b88c20ed479ed9684e249f7134618:264:u2f/assets/cert_key.u2f
 F:f60b88c20ed479ed9684e249f7134618:264:u2f/assets/cert_key.u2f

+ 0 - 19
assets/resources/subghz/assets/setting_frequency_analyzer_user

@@ -1,19 +0,0 @@
-Filetype: Flipper SubGhz Setting File
-Version: 1
-Frequency_default: 433920000
-Frequency: 300000000
-Frequency: 303875000
-Frequency: 304250000
-Frequency: 315000000
-Frequency: 318000000
-Frequency: 390000000
-Frequency: 418000000
-Frequency: 433075000
-Frequency: 433420000
-Frequency: 433920000
-Frequency: 434420000
-Frequency: 434775000
-Frequency: 438900000
-Frequency: 868350000
-Frequency: 915000000
-Frequency: 925000000

+ 16 - 22
assets/resources/subghz/assets/setting_user

@@ -1,24 +1,18 @@
 Filetype: Flipper SubGhz Setting File
 Filetype: Flipper SubGhz Setting File
 Version: 1
 Version: 1
-Frequency_default: 433920000
-Frequency: 300000000
-Frequency: 303875000
-Frequency: 304250000
-Frequency: 315000000
-Frequency: 318000000
-Frequency: 390000000
-Frequency: 418000000
-Frequency: 433075000
-Frequency: 433420000
-Frequency: 433920000
-Frequency: 434420000
-Frequency: 434775000
-Frequency: 438900000
-Frequency: 868350000
-Frequency: 915000000
-Frequency: 925000000
-Hopper_frequency: 315000000
-Hopper_frequency: 318000000
-Hopper_frequency: 390000000
-Hopper_frequency: 433920000
-Hopper_frequency: 868350000
+
+# Add Standard frequencies for your region
+#add_standard_frequencies: true
+
+# Default Frequency: used as default for "Read" and "Read Raw"
+#default_frequency: 433920000
+
+# Frequencies used for "Read", "Read Raw" and "Frequency Analyzer"
+#frequency: 300000000
+#frequency: 310000000
+#frequency: 320000000
+
+# Frequencies used for hopping mode (keep this list small or flipper will miss signal)
+#hopper_frequency: 300000000
+#hopper_frequency: 310000000
+#hopper_frequency: 310000000

+ 2 - 2
lib/subghz/protocols/came_atomo.c

@@ -108,8 +108,8 @@ void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t
     ManchesterEvent event = ManchesterEventReset;
     ManchesterEvent event = ManchesterEventReset;
     switch(instance->decoder.parser_step) {
     switch(instance->decoder.parser_step) {
     case CameAtomoDecoderStepReset:
     case CameAtomoDecoderStepReset:
-        if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 65) <
-                        subghz_protocol_came_atomo_const.te_delta * 20)) {
+        if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 60) <
+                        subghz_protocol_came_atomo_const.te_delta * 40)) {
             //Found header CAME
             //Found header CAME
             instance->decoder.parser_step = CameAtomoDecoderStepDecoderData;
             instance->decoder.parser_step = CameAtomoDecoderStepDecoderData;
             instance->decoder.decode_data = 0;
             instance->decoder.decode_data = 0;