1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

Merge pull request #590 from derskythe/feat/subghz-save-hopping-state

[FEAT] Save hopping state in SubGHz
This commit is contained in:
MMX
2023-09-11 16:38:21 +03:00
committed by GitHub
24 changed files with 472 additions and 191 deletions

View File

@@ -77,6 +77,7 @@ typedef enum {
SubGhzCustomEventSceneAnalyzerLock, SubGhzCustomEventSceneAnalyzerLock,
SubGhzCustomEventSceneAnalyzerUnlock, SubGhzCustomEventSceneAnalyzerUnlock,
SubGhzCustomEventSceneSettingLock, SubGhzCustomEventSceneSettingLock,
SubGhzCustomEventSceneSettingResetToDefault,
SubGhzCustomEventSceneExit, SubGhzCustomEventSceneExit,
SubGhzCustomEventSceneStay, SubGhzCustomEventSceneStay,

View File

@@ -3,10 +3,9 @@
#include <lib/subghz/protocols/protocol_items.h> #include <lib/subghz/protocols/protocol_items.h>
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h> #include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h> #include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
#include <lib/subghz/blocks/custom_btn.h> #include <lib/subghz/blocks/custom_btn.h>
#define TAG "SubGhz" #define TAG "SubGhzTxRx"
static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) { static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) {
UNUSED(instance); UNUSED(instance);
@@ -30,8 +29,7 @@ SubGhzTxRx* subghz_txrx_alloc() {
instance->preset = malloc(sizeof(SubGhzRadioPreset)); instance->preset = malloc(sizeof(SubGhzRadioPreset));
instance->preset->name = furi_string_alloc(); instance->preset->name = furi_string_alloc();
subghz_txrx_set_preset( subghz_txrx_set_default_preset(instance, 0);
instance, "AM650", subghz_setting_get_default_frequency(instance->setting), NULL, 0);
instance->txrx_state = SubGhzTxRxStateSleep; instance->txrx_state = SubGhzTxRxStateSleep;
@@ -380,10 +378,11 @@ void subghz_txrx_hopper_update(SubGhzTxRx* instance) {
default: default:
break; break;
} }
float rssi = -127.0f; // Init value isn't using
// float rssi = -127.0f;
if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) { if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) {
// See RSSI Calculation timings in CC1101 17.3 RSSI // 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 // Stay if RSSI is high enough
if(rssi > -90.0f) { if(rssi > -90.0f) {
@@ -404,7 +403,7 @@ void subghz_txrx_hopper_update(SubGhzTxRx* instance) {
if(instance->txrx_state == SubGhzTxRxStateRx) { if(instance->txrx_state == SubGhzTxRxStateRx) {
subghz_txrx_rx_end(instance); subghz_txrx_rx_end(instance);
}; }
if(instance->txrx_state == SubGhzTxRxStateIDLE) { if(instance->txrx_state == SubGhzTxRxStateIDLE) {
subghz_receiver_reset(instance->receiver); subghz_receiver_reset(instance->receiver);
instance->preset->frequency = instance->preset->frequency =
@@ -551,7 +550,7 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi
subghz_receiver_set_filter(instance->receiver, filter); subghz_receiver_set_filter(instance->receiver, filter);
} }
void subghz_txrx_set_rx_calback( void subghz_txrx_set_rx_callback(
SubGhzTxRx* instance, SubGhzTxRx* instance,
SubGhzReceiverCallback callback, SubGhzReceiverCallback callback,
void* context) { void* context) {
@@ -672,3 +671,31 @@ SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) {
furi_assert(instance); furi_assert(instance);
return instance->receiver; return instance->receiver;
} }
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;
}

View File

@@ -274,7 +274,7 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi
* @param callback Callback for receive data * @param callback Callback for receive data
* @param context Context for callback * @param context Context for callback
*/ */
void subghz_txrx_set_rx_calback( void subghz_txrx_set_rx_callback(
SubGhzTxRx* instance, SubGhzTxRx* instance,
SubGhzReceiverCallback callback, SubGhzReceiverCallback callback,
void* context); 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); 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 * @param instance Pointer to a SubGhzTxRx
* @return bool True if the frequency is valid * @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); void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance);
SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw 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);

View File

@@ -1,8 +1,4 @@
#include "../subghz_i.h" #include "../subghz_i.h"
#include "../views/receiver.h"
#include <lib/subghz/protocols/raw.h>
#include <lib/subghz/subghz_file_encoder_worker.h>
#define TAG "SubGhzDecodeRaw" #define TAG "SubGhzDecodeRaw"
#define SAMPLES_TO_READ_PER_TICK 400 #define SAMPLES_TO_READ_PER_TICK 400
@@ -21,13 +17,20 @@ static void subghz_scene_receiver_update_statusbar(void* context) {
subghz->subghz_receiver, subghz->subghz_receiver,
furi_string_get_cstr(frequency_str), furi_string_get_cstr(frequency_str),
furi_string_get_cstr(modulation_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(frequency_str);
furi_string_free(modulation_str); furi_string_free(modulation_str);
} else { } else {
subghz_view_receiver_add_data_statusbar( 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); 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_view_receiver_set_callback(
subghz->subghz_receiver, subghz_scene_decode_raw_callback, subghz); 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); subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_Decodable);
@@ -170,7 +173,7 @@ void subghz_scene_decode_raw_on_enter(void* context) {
} else { } else {
//Load history to receiver //Load history to receiver
subghz_view_receiver_exit(subghz->subghz_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_name);
furi_string_reset(item_time); furi_string_reset(item_time);
subghz_history_get_text_item_menu(subghz->history, item_name, i); 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->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart);
subghz->idx_menu_chosen = 0; 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)) { if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) {
subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder);

View File

@@ -1,5 +1,5 @@
#include "../subghz.h"
#include "../subghz_i.h" #include "../subghz_i.h"
#include "../helpers/subghz_custom_event.h"
void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void* context) { void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void* context) {
furi_assert(context); furi_assert(context);

View File

@@ -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); subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer);
if(frequency > 0) { if(frequency > 0) {
subghz->last_settings->frequency = frequency; subghz->last_settings->frequency = frequency;
#ifdef FURI_DEBUG
subghz_last_settings_log(subghz->last_settings);
#endif
subghz_last_settings_save(subghz->last_settings); subghz_last_settings_save(subghz->last_settings);
} }

View File

@@ -104,8 +104,15 @@ void subghz_scene_read_raw_on_enter(void* context) {
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) { if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); 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); subghz_scene_read_raw_update_statusbar(subghz);
//set callback view raw //set callback view raw
@@ -115,6 +122,8 @@ void subghz_scene_read_raw_on_enter(void* context) {
//set filter RAW feed //set filter RAW feed
subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_RAW); subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_RAW);
furi_string_free(file_name);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW); 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 { } else {
//Restore default setting //Restore default setting
if(subghz->raw_send_only) { if(subghz->raw_send_only) {
subghz_set_default_preset(subghz); subghz_txrx_set_default_preset(subghz->txrx, 0);
} else { } else {
subghz_txrx_set_preset( subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency);
subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
} }
if(!scene_manager_search_and_switch_to_previous_scene( if(!scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneSaved)) { subghz->scene_manager, SubGhzSceneSaved)) {

View File

@@ -1,5 +1,4 @@
#include "../subghz_i.h" #include "../subghz_i.h"
#include "../views/receiver.h"
#include <dolphin/dolphin.h> #include <dolphin/dolphin.h>
#include <lib/subghz/protocols/bin_raw.h> #include <lib/subghz/protocols/bin_raw.h>
@@ -70,13 +69,20 @@ static void subghz_scene_receiver_update_statusbar(void* context) {
subghz->subghz_receiver, subghz->subghz_receiver,
furi_string_get_cstr(frequency_str), furi_string_get_cstr(frequency_str),
furi_string_get_cstr(modulation_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(frequency_str);
furi_string_free(modulation_str); furi_string_free(modulation_str);
} else { } else {
subghz_view_receiver_add_data_statusbar( 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; subghz->state_notifications = SubGhzNotificationStateIDLE;
} }
furi_string_free(history_stat_str); furi_string_free(history_stat_str);
@@ -142,7 +148,17 @@ void subghz_scene_receiver_on_enter(void* context) {
FuriString* item_time = furi_string_alloc(); FuriString* item_time = furi_string_alloc();
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) { 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_history_reset(history);
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart);
subghz->idx_menu_chosen = 0; subghz->idx_menu_chosen = 0;
@@ -153,7 +169,7 @@ void subghz_scene_receiver_on_enter(void* context) {
// Load history to receiver // Load history to receiver
subghz_view_receiver_exit(subghz->subghz_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_name);
furi_string_reset(item_time); furi_string_reset(item_time);
subghz_history_get_text_item_menu(history, item_name, i); 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_name);
furi_string_free(item_time); furi_string_free(item_time);
subghz_view_receiver_set_callback( subghz_view_receiver_set_callback(
subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); 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)) { if(!subghz_history_get_text_space_left(subghz->history, NULL)) {
subghz->state_notifications = SubGhzNotificationStateRx; 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_txrx_rx_start(subghz->txrx);
subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->idx_menu_chosen); 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->state_notifications = SubGhzNotificationStateIDLE;
subghz_txrx_stop(subghz->txrx); subghz_txrx_stop(subghz->txrx);
subghz_txrx_hopper_set_state(subghz->txrx, SubGhzHopperStateOFF); 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) { if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateAddKey) {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateExit);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else { } else {
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
subghz_txrx_set_preset( subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency);
subghz->txrx, "AM650", subghz->last_settings->frequency, NULL, 0);
scene_manager_search_and_switch_to_previous_scene( scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneStart); subghz->scene_manager, SubGhzSceneStart);
} }

View File

@@ -1,6 +1,8 @@
#include "../subghz_i.h" #include "../subghz_i.h"
#include <lib/toolbox/value_index.h> #include <lib/toolbox/value_index.h>
#define TAG "SubGhzSceneReceiverConfig"
enum SubGhzSettingIndex { enum SubGhzSettingIndex {
SubGhzSettingIndexFrequency, SubGhzSettingIndexFrequency,
SubGhzSettingIndexHopping, SubGhzSettingIndexHopping,
@@ -10,6 +12,7 @@ enum SubGhzSettingIndex {
SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreCars,
SubGhzSettingIndexIgnoreMagellan, SubGhzSettingIndexIgnoreMagellan,
SubGhzSettingIndexSound, SubGhzSettingIndexSound,
SubGhzSettingIndexResetToDefault,
SubGhzSettingIndexLock, SubGhzSettingIndexLock,
SubGhzSettingIndexRAWThresholdRSSI, SubGhzSettingIndexRAWThresholdRSSI,
}; };
@@ -43,47 +46,51 @@ const float raw_threshold_rssi_value[RAW_THRESHOLD_RSSI_COUNT] = {
-40.0f, -40.0f,
}; };
#define HOPPING_COUNT 2 #define COMBO_BOX_COUNT 2
const char* const hopping_text[HOPPING_COUNT] = {
"OFF", const uint32_t hopping_value[COMBO_BOX_COUNT] = {
"ON",
};
const uint32_t hopping_value[HOPPING_COUNT] = {
SubGhzHopperStateOFF, SubGhzHopperStateOFF,
SubGhzHopperStateRunning, SubGhzHopperStateRunning,
}; };
#define SPEAKER_COUNT 2 const uint32_t speaker_value[COMBO_BOX_COUNT] = {
const char* const speaker_text[SPEAKER_COUNT] = {
"OFF",
"ON",
};
const uint32_t speaker_value[SPEAKER_COUNT] = {
SubGhzSpeakerStateShutdown, SubGhzSpeakerStateShutdown,
SubGhzSpeakerStateEnable, SubGhzSpeakerStateEnable,
}; };
#define BIN_RAW_COUNT 2
const char* const bin_raw_text[BIN_RAW_COUNT] = { const uint32_t bin_raw_value[COMBO_BOX_COUNT] = {
"OFF",
"ON",
};
const uint32_t bin_raw_value[BIN_RAW_COUNT] = {
SubGhzProtocolFlag_Decodable, SubGhzProtocolFlag_Decodable,
SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_BinRAW, 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", "OFF",
"ON", "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) { uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) {
furi_assert(context); furi_assert(context);
SubGhz* subghz = context; SubGhz* subghz = context;
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
uint8_t index = 0; 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)) { if(value == subghz_setting_get_frequency(setting, i)) {
index = i; index = i;
break; break;
@@ -100,7 +107,7 @@ uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void*
uint8_t index = 0; uint8_t index = 0;
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); 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)) { if(!strcmp(subghz_setting_get_preset_name(setting, i), preset_name)) {
index = i; index = i;
break; break;
@@ -111,23 +118,18 @@ uint8_t subghz_scene_receiver_config_next_preset(const char* preset_name, void*
return index; return index;
} }
uint8_t subghz_scene_receiver_config_hopper_value_index( SubGhzHopperState subghz_scene_receiver_config_hopper_value_index(void* context) {
const uint32_t value,
const uint32_t values[],
uint8_t values_count,
void* context) {
furi_assert(context); furi_assert(context);
UNUSED(values_count);
SubGhz* subghz = context; SubGhz* subghz = context;
if(value == values[0]) { if(subghz_txrx_hopper_get_state(subghz->txrx) == SubGhzHopperStateOFF) {
return 0; return SubGhzHopperStateOFF;
} else { } else {
variable_item_set_current_value_text( variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state( (VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig), subghz->scene_manager, SubGhzSceneReceiverConfig),
" -----"); " -----");
return 1; return SubGhzHopperStateRunning;
} }
} }
@@ -180,17 +182,19 @@ static void subghz_scene_receiver_config_set_preset(VariableItem* item) {
preset.frequency, preset.frequency,
subghz_setting_get_preset_data(setting, index), subghz_setting_get_preset_data(setting, index),
subghz_setting_get_preset_data_size(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) { static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(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); SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
VariableItem* frequency_item = (VariableItem*)scene_manager_get_scene_state( VariableItem* frequency_item = (VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig); subghz->scene_manager, SubGhzSceneReceiverConfig);
variable_item_set_current_value_text(item, hopping_text[index]); variable_item_set_current_value_text(item, combobox_text[(uint8_t)index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
if(index == SubGhzHopperStateOFF) {
char text_buf[10] = {0}; char text_buf[10] = {0};
uint32_t frequency = subghz_setting_get_default_frequency(setting); uint32_t frequency = subghz_setting_get_default_frequency(setting);
SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); 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); (frequency % 1000000) / 10000);
variable_item_set_current_value_text(frequency_item, text_buf); 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_set_preset(
subghz->txrx, subghz->txrx,
furi_string_get_cstr(preset.name), 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( variable_item_set_current_value_index(
frequency_item, subghz_setting_get_frequency_default_index(setting)); frequency_item, subghz_setting_get_frequency_default_index(setting));
} }
subghz->last_settings->enable_hopping = index != SubGhzHopperStateOFF;
subghz_txrx_hopper_set_state(subghz->txrx, hopping_value[index]); subghz_txrx_hopper_set_state(subghz->txrx, index);
} }
static void subghz_scene_receiver_config_set_speaker(VariableItem* item) { static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item); SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(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]); 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); SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(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->filter = bin_raw_value[index];
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); 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) { 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]); 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_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( static inline bool subghz_scene_receiver_config_ignore_filter_get_index(
SubGhzProtocolFlag filter, SubGhzProtocolFlag filter,
SubGhzProtocolFlag flag) { SubGhzProtocolFlag flag) {
@@ -282,6 +279,46 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context,
if(index == SubGhzSettingIndexLock) { if(index == SubGhzSettingIndexLock) {
view_dispatcher_send_custom_event( view_dispatcher_send_custom_event(
subghz->view_dispatcher, SubGhzCustomEventSceneSettingLock); 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Hopping:", "Hopping:",
HOPPING_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_hopping_running, subghz_scene_receiver_config_set_hopping_running,
subghz); subghz);
value_index = subghz_scene_receiver_config_hopper_value_index( value_index = subghz_scene_receiver_config_hopper_value_index(subghz);
subghz_txrx_hopper_get_state(subghz->txrx), hopping_value, HOPPING_COUNT, subghz);
variable_item_set_current_value_index(item, value_index); 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) != 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Bin RAW:", "Bin RAW:",
BIN_RAW_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_bin_raw, subghz_scene_receiver_config_set_bin_raw,
subghz); 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_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) != 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Ignore Starline:", "Ignore Starline:",
PROTOCOL_IGNORE_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_starline, subghz_scene_receiver_config_set_starline,
subghz); subghz);
value_index = subghz_scene_receiver_config_ignore_filter_get_index( value_index = subghz_scene_receiver_config_ignore_filter_get_index(
subghz->ignore_filter, SubGhzProtocolFlag_StarLine); subghz->ignore_filter, SubGhzProtocolFlag_StarLine);
variable_item_set_current_value_index(item, value_index); 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Ignore Cars:", "Ignore Cars:",
PROTOCOL_IGNORE_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_auto_alarms, subghz_scene_receiver_config_set_auto_alarms,
subghz); subghz);
value_index = subghz_scene_receiver_config_ignore_filter_get_index( value_index = subghz_scene_receiver_config_ignore_filter_get_index(
subghz->ignore_filter, SubGhzProtocolFlag_AutoAlarms); subghz->ignore_filter, SubGhzProtocolFlag_AutoAlarms);
variable_item_set_current_value_index(item, value_index); 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Ignore Magellan:", "Ignore Magellan:",
PROTOCOL_IGNORE_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_magellan, subghz_scene_receiver_config_set_magellan,
subghz); subghz);
value_index = subghz_scene_receiver_config_ignore_filter_get_index( value_index = subghz_scene_receiver_config_ignore_filter_get_index(
subghz->ignore_filter, SubGhzProtocolFlag_Magelan); subghz->ignore_filter, SubGhzProtocolFlag_Magelan);
variable_item_set_current_value_index(item, value_index); 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 :) // 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( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Sound:", "Sound:",
SPEAKER_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_speaker, subghz_scene_receiver_config_set_speaker,
subghz); subghz);
value_index = value_index_uint32( 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_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) != if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) { SubGhzCustomEventManagerSet) {
// Lock keyboard // Lock keyboard
@@ -412,6 +460,7 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz_scene_receiver_config_var_list_enter_callback, subghz_scene_receiver_config_var_list_enter_callback,
subghz); subghz);
} }
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) ==
SubGhzCustomEventManagerSet) { SubGhzCustomEventManagerSet) {
item = variable_item_list_add( item = variable_item_list_add(
@@ -439,6 +488,9 @@ bool subghz_scene_receiver_config_on_event(void* context, SceneManagerEvent even
subghz_lock(subghz); subghz_lock(subghz);
scene_manager_previous_scene(subghz->scene_manager); scene_manager_previous_scene(subghz->scene_manager);
consumed = true; consumed = true;
} else if(event.event == SubGhzCustomEventSceneSettingResetToDefault) {
scene_manager_previous_scene(subghz->scene_manager);
consumed = true;
} }
} }
return consumed; return consumed;
@@ -448,6 +500,9 @@ void subghz_scene_receiver_config_on_exit(void* context) {
SubGhz* subghz = context; SubGhz* subghz = context;
variable_item_list_set_selected_item(subghz->variable_item_list, 0); variable_item_list_set_selected_item(subghz->variable_item_list, 0);
variable_item_list_reset(subghz->variable_item_list); 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); subghz_last_settings_save(subghz->last_settings);
scene_manager_set_scene_state( scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);

View File

@@ -1,8 +1,9 @@
#include "../subghz_i.h" #include "../subghz_i.h"
#include "../helpers/subghz_custom_event.h"
#include <lib/subghz/blocks/custom_btn.h> #include <lib/subghz/blocks/custom_btn.h>
#define TAG "SubGhzSceneReceiverInfo"
void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) {
furi_assert(context); furi_assert(context);
SubGhz* subghz = context; SubGhz* subghz = context;

View File

@@ -42,7 +42,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event)
subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart); subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart);
subghz->idx_menu_chosen = 0; 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)) { if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) {
subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder);

View File

@@ -1,5 +1,7 @@
#include "../subghz_i.h" #include "../subghz_i.h"
#define TAG "SubGhzSceneSaved"
void subghz_scene_saved_on_enter(void* context) { void subghz_scene_saved_on_enter(void* context) {
SubGhz* subghz = context; SubGhz* subghz = context;

View File

@@ -4,6 +4,8 @@
#include <lib/subghz/blocks/custom_btn.h> #include <lib/subghz/blocks/custom_btn.h>
#define TAG "SubGhzSceneTransmitter"
void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) {
furi_assert(context); furi_assert(context);
SubGhz* subghz = context; SubGhz* subghz = context;

View File

@@ -1,9 +1,10 @@
/* Abandon hope, all ye who enter here. */ /* Abandon hope, all ye who enter here. */
#include <furi/core/log.h>
#include <subghz/types.h> #include <subghz/types.h>
#include <lib/toolbox/path.h> #include <lib/toolbox/path.h>
#include <float_tools.h>
#include "subghz_i.h" #include "subghz_i.h"
#include <lib/subghz/protocols/protocol_items.h>
#define TAG "SubGhzApp" #define TAG "SubGhzApp"
@@ -73,7 +74,7 @@ static void subghz_load_custom_presets(SubGhzSetting* setting) {
FlipperFormat* fff_temp = flipper_format_string_alloc(); 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_insert_or_update_string_cstr(fff_temp, "Custom_preset_data", presets[i][1]);
flipper_format_rewind(fff_temp); flipper_format_rewind(fff_temp);
@@ -111,7 +112,9 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
// Open Notification record // Open Notification record
subghz->notifications = furi_record_open(RECORD_NOTIFICATION); subghz->notifications = furi_record_open(RECORD_NOTIFICATION);
#if SUBGHZ_MEASURE_LOADING
uint32_t load_ticks = furi_get_tick();
#endif
subghz->txrx = subghz_txrx_alloc(); subghz->txrx = subghz_txrx_alloc();
if(!alloc_for_tx_only) { 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 // Load last used values for Read, Read RAW, etc. or default
subghz->last_settings = subghz_last_settings_alloc(); subghz->last_settings = subghz_last_settings_alloc();
subghz_last_settings_load(subghz->last_settings, 0); size_t preset_count = subghz_setting_get_preset_count(setting);
if(!alloc_for_tx_only) { subghz_last_settings_load(subghz->last_settings, preset_count);
#if FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D( subghz_last_settings_log(subghz->last_settings);
TAG,
"last frequency: %ld, preset: %ld",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#endif #endif
subghz_setting_set_default_frequency(setting, subghz->last_settings->frequency);
}
if(!alloc_for_tx_only) { 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); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
if(!alloc_for_tx_only) {
subghz->history = subghz_history_alloc();
}
subghz->secure_data = malloc(sizeof(SecureData)); subghz->secure_data = malloc(sizeof(SecureData));
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->filter = SubGhzProtocolFlag_Decodable;
subghz->ignore_filter = 0x0; subghz->ignore_filter = 0x0;
}
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter);
subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz); 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 //Init Error_str
subghz->error_str = furi_string_alloc(); subghz->error_str = furi_string_alloc();

View File

@@ -4,30 +4,13 @@
#include "subghz/types.h" #include "subghz/types.h"
#include <math.h> #include <math.h>
#include <furi.h> #include <furi.h>
#include <furi_hal.h>
#include <input/input.h>
#include <gui/elements.h>
#include <notification/notification.h> #include <notification/notification.h>
#include <notification/notification_messages.h> #include <notification/notification_messages.h>
#include <flipper_format/flipper_format.h> #include <flipper_format/flipper_format.h>
#include "views/receiver.h"
#include <flipper_format/flipper_format_i.h> #include <flipper_format/flipper_format_i.h>
#include <lib/toolbox/stream/stream.h>
#include <lib/subghz/protocols/raw.h>
#define TAG "SubGhz" #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) { void subghz_blink_start(SubGhz* subghz) {
furi_assert(subghz); furi_assert(subghz);
notification_message(subghz->notifications, &sequence_blink_stop); 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; DialogsApp* dialogs = subghz->dialogs;
DialogMessage* message = dialog_message_alloc(); DialogMessage* message = dialog_message_alloc();
const char* header_text = "Frequency not supported"; 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) { if(only_rx) {
header_text = "Transmission is blocked"; 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) // TODO: use different frequency allowed lists for differnet modules (non cc1101)
if(!furi_hal_subghz_is_tx_allowed(temp_data32)) { if(!furi_hal_subghz_is_tx_allowed(temp_data32)) {
FURI_LOG_E(TAG, "This frequency can only be used for RX"); FURI_LOG_E(TAG, "This frequency can only be used for RX");
load_key_state = SubGhzLoadKeyStateOnlyRx; load_key_state = SubGhzLoadKeyStateOnlyRx;
break; break;
} }

View File

@@ -42,6 +42,8 @@
#define SUBGHZ_MAX_LEN_NAME 64 #define SUBGHZ_MAX_LEN_NAME 64
#define SUBGHZ_EXT_PRESET_NAME true #define SUBGHZ_EXT_PRESET_NAME true
#define SUBGHZ_RAW_THRESHOLD_MIN (-90.0f)
#define SUBGHZ_MEASURE_LOADING false
typedef struct { typedef struct {
uint8_t fix[4]; uint8_t fix[4];
@@ -98,7 +100,6 @@ struct SubGhz {
void* rpc_ctx; void* rpc_ctx;
}; };
void subghz_set_default_preset(SubGhz* subghz);
void subghz_blink_start(SubGhz* subghz); void subghz_blink_start(SubGhz* subghz);
void subghz_blink_stop(SubGhz* subghz); void subghz_blink_stop(SubGhz* subghz);

View File

@@ -6,21 +6,19 @@
#define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File" #define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File"
#define SUBGHZ_LAST_SETTING_FILE_VERSION 1 #define SUBGHZ_LAST_SETTING_FILE_VERSION 1
#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/last_subghz.settings") #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_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_FEEDBACK_LEVEL "FeedbackLevel"
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger" #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_ENABLED "External"
#define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER "ExtPower" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER "ExtPower"
#define SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES "TimestampNames" #define SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES "TimestampNames"
#define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER_AMP "ExtPowerAmp" #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* subghz_last_settings_alloc(void) {
SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); 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) { void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) {
UNUSED(preset_count);
furi_assert(instance); furi_assert(instance);
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "subghz_last_settings_load");
#endif
Storage* storage = furi_record_open(RECORD_STORAGE); Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* fff_data_file = flipper_format_file_alloc(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_5v_disable = false;
bool temp_external_module_power_amp = false; bool temp_external_module_power_amp = false;
bool temp_timestamp_file_names = 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_feedback_level_was_read = false;
bool frequency_analyzer_trigger_was_read = false; bool frequency_analyzer_trigger_was_read = false;
if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH && 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_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) {
/* preset_was_read = flipper_format_read_uint32(
flipper_format_read_int32( fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (uint32_t*)&temp_preset, 1);
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (int32_t*)&temp_preset, 1);*/
flipper_format_read_uint32( flipper_format_read_uint32(
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1); fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1);
frequency_analyzer_feedback_level_was_read = flipper_format_read_uint32( 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, SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER_AMP,
(bool*)&temp_external_module_power_amp, (bool*)&temp_external_module_power_amp,
1); 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 { } else {
FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH); FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH);
} }
if(temp_frequency == 0 || !furi_hal_subghz_is_tx_allowed(temp_frequency)) { 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!"); FURI_LOG_W(TAG, "Last used frequency not found or can't be used!");
instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY; 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 = instance->frequency_analyzer_feedback_level =
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL; SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL;
instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
instance->external_module_enabled = false; instance->external_module_enabled = false;
instance->timestamp_file_names = false; instance->timestamp_file_names = false;
instance->external_module_power_amp = 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 { } else {
instance->frequency = temp_frequency; instance->frequency = temp_frequency;
instance->frequency_analyzer_feedback_level = instance->frequency_analyzer_feedback_level =
@@ -117,10 +137,19 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
temp_frequency_analyzer_trigger : temp_frequency_analyzer_trigger :
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
/*if(temp_preset > (int32_t)preset_count - 1 || temp_preset < 0) { if(!preset_was_read) {
FURI_LOG_W(TAG, "Last used preset no found");*/ FURI_LOG_W(TAG, "Preset was not read. Set default");
instance->preset = SUBGHZ_LAST_SETTING_DEFAULT_PRESET; 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_enabled = temp_external_module_enabled;
instance->external_module_power_5v_disable = temp_external_module_power_5v_disable; 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 // External power amp CC1101
instance->external_module_power_amp = temp_external_module_power_amp; 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 // Set globally in furi hal
furi_hal_subghz_set_ext_power_amp(instance->external_module_power_amp); furi_hal_subghz_set_ext_power_amp(instance->external_module_power_amp);
/*/} else {
instance->preset = temp_preset;
}*/
} }
flipper_format_file_close(fff_data_file); 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) { bool subghz_last_settings_save(SubGhzLastSettings* instance) {
furi_assert(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; bool saved = false;
Storage* storage = furi_record_open(RECORD_STORAGE); Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* file = flipper_format_file_alloc(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( if(!flipper_format_write_header_cstr(
file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION)) file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION))
break; break;
if(!flipper_format_insert_or_update_uint32(
/* file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset_index, 1)) {
if(!flipper_format_insert_or_update_int32(
file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset, 1)) {
break; break;
}*/ }
if(!flipper_format_insert_or_update_uint32( if(!flipper_format_insert_or_update_uint32(
file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) { file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) {
break; break;
@@ -217,6 +254,22 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
1)) { 1)) {
break; 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; saved = true;
} while(0); } while(0);
@@ -230,3 +283,43 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
return saved; 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));
}

View File

@@ -4,10 +4,20 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <storage/storage.h> #include <storage/storage.h>
#include <lib/subghz/types.h>
#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 { typedef struct {
uint32_t frequency; uint32_t frequency;
int32_t preset; uint32_t preset_index; // AKA Modulation
uint32_t frequency_analyzer_feedback_level; uint32_t frequency_analyzer_feedback_level;
float frequency_analyzer_trigger; float frequency_analyzer_trigger;
// TODO not using but saved so as not to change the version // TODO not using but saved so as not to change the version
@@ -16,6 +26,10 @@ typedef struct {
bool external_module_power_amp; bool external_module_power_amp;
// saved so as not to change the version // saved so as not to change the version
bool timestamp_file_names; bool timestamp_file_names;
bool enable_hopping;
uint32_t ignore_filter;
uint32_t filter;
float rssi;
} SubGhzLastSettings; } SubGhzLastSettings;
SubGhzLastSettings* subghz_last_settings_alloc(void); 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); void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count);
bool subghz_last_settings_save(SubGhzLastSettings* instance); bool subghz_last_settings_save(SubGhzLastSettings* instance);
void subghz_last_settings_log(SubGhzLastSettings* instance);

View File

@@ -12,7 +12,7 @@
#define MENU_ITEMS 4u #define MENU_ITEMS 4u
#define UNLOCK_CNT 3 #define UNLOCK_CNT 3
#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f // #define SUBGHZ_RAW_THRESHOLD_MIN (-90.0f)
#define FLIP_TIMEOUT (500) #define FLIP_TIMEOUT (500)
@@ -62,6 +62,8 @@ typedef struct {
FuriString* preset_str; FuriString* preset_str;
FuriString* history_stat_str; FuriString* history_stat_str;
FuriString* progress_str; FuriString* progress_str;
bool hopping_enabled;
bool bin_raw_enabled;
SubGhzReceiverHistory* history; SubGhzReceiverHistory* history;
uint16_t idx; uint16_t idx;
uint16_t list_offset; uint16_t list_offset;
@@ -200,7 +202,9 @@ void subghz_view_receiver_add_data_statusbar(
SubGhzViewReceiver* subghz_receiver, SubGhzViewReceiver* subghz_receiver,
const char* frequency_str, const char* frequency_str,
const char* preset_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); furi_assert(subghz_receiver);
with_view_model( with_view_model(
subghz_receiver->view, 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->frequency_str, frequency_str);
furi_string_set(model->preset_str, preset_str); furi_string_set(model->preset_str, preset_str);
furi_string_set(model->history_stat_str, history_stat_str); furi_string_set(model->history_stat_str, history_stat_str);
model->hopping_enabled = hopping_enabled;
model->bin_raw_enabled = bin_raw_enabled;
}, },
true); true);
} }
@@ -311,7 +317,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
if(model->history_item == 0) { if(model->history_item == 0) {
// TODO
if(model->mode == SubGhzViewReceiverModeLive) { if(model->mode == SubGhzViewReceiverModeLive) {
canvas_draw_icon( canvas_draw_icon(
canvas, canvas,
@@ -320,9 +325,19 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
(model->device_type == SubGhzRadioDeviceTypeInternal) ? &I_Scanning_123x52 : (model->device_type == SubGhzRadioDeviceTypeInternal) ? &I_Scanning_123x52 :
&I_Fishing_123x52); &I_Fishing_123x52);
canvas_set_font(canvas, FontPrimary); 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_draw_line(canvas, 46, 51, 125, 51);
canvas_set_font(canvas, FontSecondary); 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 { } else {
canvas_draw_icon( canvas_draw_icon(
canvas, canvas,
@@ -458,8 +473,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) {
return true; return true;
} }
bool consumed = false;
if(event->key == InputKeyBack && event->type == InputTypeShort) { if(event->key == InputKeyBack && event->type == InputTypeShort) {
subghz_receiver->callback(SubGhzCustomEventViewReceiverBack, subghz_receiver->context); subghz_receiver->callback(SubGhzCustomEventViewReceiverBack, subghz_receiver->context);
consumed = true;
} else if( } else if(
event->key == InputKeyUp && event->key == InputKeyUp &&
(event->type == InputTypeShort || event->type == InputTypeRepeat)) { (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); subghz_view_receiver_show_time_moment(context);
}, },
true); true);
consumed = true;
} else if( } else if(
event->key == InputKeyDown && event->key == InputKeyDown &&
(event->type == InputTypeShort || event->type == InputTypeRepeat)) { (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
@@ -484,8 +502,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) {
} }
}, },
true); true);
consumed = true;
} else if(event->key == InputKeyLeft && event->type == InputTypeShort) { } else if(event->key == InputKeyLeft && event->type == InputTypeShort) {
subghz_receiver->callback(SubGhzCustomEventViewReceiverConfig, subghz_receiver->context); subghz_receiver->callback(SubGhzCustomEventViewReceiverConfig, subghz_receiver->context);
consumed = true;
} else if(event->key == InputKeyRight && event->type == InputTypeLong) { } else if(event->key == InputKeyRight && event->type == InputTypeLong) {
with_view_model( with_view_model(
subghz_receiver->view, subghz_receiver->view,
@@ -498,6 +518,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) {
} }
}, },
false); false);
consumed = true;
} else if(event->key == InputKeyOk && event->type == InputTypeShort) { } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
with_view_model( with_view_model(
subghz_receiver->view, subghz_receiver->view,
@@ -509,11 +530,13 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) {
} }
}, },
false); false);
consumed = true;
} }
if(consumed) {
subghz_view_receiver_update_offset(subghz_receiver); subghz_view_receiver_update_offset(subghz_receiver);
}
return true; return consumed;
} }
void subghz_view_receiver_enter(void* context) { void subghz_view_receiver_enter(void* context) {
@@ -543,6 +566,8 @@ void subghz_view_receiver_exit(void* context) {
model->list_offset = 0; model->list_offset = 0;
model->history_item = 0; model->history_item = 0;
model->nodraw = false; model->nodraw = false;
model->hopping_enabled = false;
model->bin_raw_enabled = false;
}, },
false); false);
furi_timer_stop(subghz_receiver->timer); furi_timer_stop(subghz_receiver->timer);
@@ -579,6 +604,8 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() {
model->bar_show = SubGhzViewReceiverBarShowDefault; model->bar_show = SubGhzViewReceiverBarShowDefault;
model->nodraw = false; model->nodraw = false;
model->history = malloc(sizeof(SubGhzReceiverHistory)); model->history = malloc(sizeof(SubGhzReceiverHistory));
model->hopping_enabled = false;
model->bin_raw_enabled = false;
SubGhzReceiverMenuItemArray_init(model->history->data); SubGhzReceiverMenuItemArray_init(model->history->data);
}, },
true); 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) { uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver) {
furi_assert(subghz_receiver); furi_assert(subghz_receiver);
uint16_t idx = 0; uint16_t idx;
with_view_model( with_view_model(
subghz_receiver->view, SubGhzViewReceiverModel * model, { idx = model->idx; }, false); subghz_receiver->view, SubGhzViewReceiverModel * model, { idx = model->idx; }, false);
return idx; return idx;

View File

@@ -31,7 +31,9 @@ void subghz_view_receiver_add_data_statusbar(
SubGhzViewReceiver* subghz_receiver, SubGhzViewReceiver* subghz_receiver,
const char* frequency_str, const char* frequency_str,
const char* preset_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( void subghz_view_receiver_set_radio_device_type(
SubGhzViewReceiver* subghz_receiver, SubGhzViewReceiver* subghz_receiver,

View File

@@ -4,8 +4,6 @@
#include "../helpers/subghz_types.h" #include "../helpers/subghz_types.h"
#include "../helpers/subghz_custom_event.h" #include "../helpers/subghz_custom_event.h"
#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f
typedef struct SubGhzReadRAW SubGhzReadRAW; typedef struct SubGhzReadRAW SubGhzReadRAW;
typedef void (*SubGhzReadRAWCallback)(SubGhzCustomEvent event, void* context); typedef void (*SubGhzReadRAWCallback)(SubGhzCustomEvent event, void* context);

View File

@@ -473,6 +473,7 @@ void cli_commands_init(Cli* cli) {
cli_add_command(cli, "uptime", CliCommandFlagDefault, cli_command_uptime, NULL); cli_add_command(cli, "uptime", CliCommandFlagDefault, cli_command_uptime, NULL);
cli_add_command(cli, "date", CliCommandFlagParallelSafe, cli_command_date, 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, "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, "sysctl", CliCommandFlagDefault, cli_command_sysctl, NULL);
cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL); cli_add_command(cli, "ps", CliCommandFlagParallelSafe, cli_command_ps, NULL);
cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL); cli_add_command(cli, "free", CliCommandFlagParallelSafe, cli_command_free, NULL);

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B