Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkorpionm <85568270+Skorpionm@users.noreply.github.com>2021-08-28 16:51:48 +0300
committerGitHub <noreply@github.com>2021-08-28 16:51:48 +0300
commit0a8a944e100c79432773ef3b6e749ab065e46cd1 (patch)
treeddde4e2a185a517a021431958d3b46af6fe139da /applications/subghz
parentc3a1836fcd67d0511f8c186afd5ffdfa9f3f699e (diff)
Skorp subghz signal archive (#667)
* SubGhz: Add millis() furi, add subghz history struct * SubGhz: Fix subghz history * Gubghz: Fix code repeat history, add clean history * SubGhz: reading and adding keys to history * Gui: Renaming Sub 1-Ghz -> SubGhz * Archive: Renaming Sub 1-Ghz -> SubGhz * SubGhz: Add menu history, modified button for sending a signal, changed output of data about accepted protocol * Archive: Fix name subghz * SubGhz: Menu navigation * Assets: Add assets/SubGHz/icon.png * Assets: add new icons for subghz * SubGhz: Fix name Add manually scene * SubGhz: Fix load icon Read scene. rename encoder struct, rename protocol function load from file, add load raw data protocol, add info pleasant signals all protocol * SubGhz: fix memory leak * SubGhz: change of receiving frequency for read scene * SubGhz: Add save/load frequency and preset, add automatic configuration of transmit/receive to the desired frequency and modulation, add button "save" config scene * SubGhz: Fix frequency and preset, fix frequency add manualli scene, fix re-executing the parser * Furi-hal-subghz: add 2-FSK config, fix ook config 650KHz BW Tx filter * Fix formatting and release build * SubGhz: Delete read scene * SubGhz: Fix frequency add manualli scene, refactoring code * SubGhz: 2 profiles for OOK, fix broken build. * SubGhz: Add passing static codes from read scene, add notification read scene, refactoring code * SubGhz: fix assert on worker double stop. Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Diffstat (limited to 'applications/subghz')
-rw-r--r--applications/subghz/scenes/subghz_scene_config.h1
-rw-r--r--applications/subghz/scenes/subghz_scene_read.c62
-rw-r--r--applications/subghz/scenes/subghz_scene_receiver.c49
-rw-r--r--applications/subghz/scenes/subghz_scene_save_name.c2
-rw-r--r--applications/subghz/scenes/subghz_scene_saved.c2
-rw-r--r--applications/subghz/scenes/subghz_scene_set_type.c16
-rw-r--r--applications/subghz/scenes/subghz_scene_start.c5
-rw-r--r--applications/subghz/scenes/subghz_scene_transmitter.c2
-rw-r--r--applications/subghz/subghz_cli.c10
-rw-r--r--applications/subghz/subghz_history.c155
-rw-r--r--applications/subghz/subghz_history.h22
-rw-r--r--applications/subghz/subghz_i.c128
-rw-r--r--applications/subghz/subghz_i.h16
-rw-r--r--applications/subghz/views/subghz_analyze.c4
-rw-r--r--applications/subghz/views/subghz_receiver.c435
-rw-r--r--applications/subghz/views/subghz_receiver.h19
-rw-r--r--applications/subghz/views/subghz_static.c2
-rw-r--r--applications/subghz/views/subghz_test_carrier.c2
-rw-r--r--applications/subghz/views/subghz_test_packet.c2
-rw-r--r--applications/subghz/views/subghz_transmitter.c60
-rw-r--r--applications/subghz/views/subghz_transmitter.h4
21 files changed, 859 insertions, 139 deletions
diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h
index 460001d2..514abd38 100644
--- a/applications/subghz/scenes/subghz_scene_config.h
+++ b/applications/subghz/scenes/subghz_scene_config.h
@@ -1,6 +1,5 @@
ADD_SCENE(subghz, start, Start)
ADD_SCENE(subghz, analyze, Analyze)
-ADD_SCENE(subghz, read, Read)
ADD_SCENE(subghz, receiver, Receiver)
ADD_SCENE(subghz, save_name, SaveName)
ADD_SCENE(subghz, save_success, SaveSuccess)
diff --git a/applications/subghz/scenes/subghz_scene_read.c b/applications/subghz/scenes/subghz_scene_read.c
deleted file mode 100644
index 7cab340d..00000000
--- a/applications/subghz/scenes/subghz_scene_read.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "../subghz_i.h"
-
-#define GUBGHZ_READ_CUSTOM_EVENT (10UL)
-
-void subghz_read_protocol_callback(SubGhzProtocolCommon* parser, void* context) {
- furi_assert(context);
- SubGhz* subghz = context;
- subghz->protocol_result = parser;
- view_dispatcher_send_custom_event(subghz->view_dispatcher, GUBGHZ_READ_CUSTOM_EVENT);
-}
-void subghz_scene_read_callback(DialogExResult result, void* context) {
- SubGhz* subghz = context;
- view_dispatcher_send_custom_event(subghz->view_dispatcher, result);
-}
-
-const void subghz_scene_read_on_enter(void* context) {
- SubGhz* subghz = context;
-
- // Setup view
- DialogEx* dialog_ex = subghz->dialog_ex;
-
- dialog_ex_set_header(dialog_ex, "SubGhz 433.92", 36, 6, AlignLeft, AlignCenter);
- dialog_ex_set_icon(dialog_ex, 10, 12, &I_RFIDDolphinReceive_97x61);
-
- //Start CC1101 rx
- subghz_begin(FuriHalSubGhzPresetOokAsync);
- subghz_rx(433920000);
-
- furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->worker);
- subghz_worker_start(subghz->worker);
- subghz_protocol_enable_dump(subghz->protocol, subghz_read_protocol_callback, subghz);
-
- view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewDialogEx);
-}
-
-const bool subghz_scene_read_on_event(void* context, SceneManagerEvent event) {
- SubGhz* subghz = context;
- if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == GUBGHZ_READ_CUSTOM_EVENT) {
- scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
- notification_message(subghz->notifications, &sequence_success);
- return true;
- }
- } else if(event.type == SceneManagerEventTypeTick) {
- notification_message(subghz->notifications, &sequence_blink_blue_10);
- return true;
- }
- return false;
-}
-
-const void subghz_scene_read_on_exit(void* context) {
- SubGhz* subghz = context;
-
- // Stop CC1101
- subghz_worker_stop(subghz->worker);
- furi_hal_subghz_stop_async_rx();
- subghz_end();
-
- DialogEx* dialog_ex = subghz->dialog_ex;
- dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
- dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
-}
diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c
index 1fe9a466..f0607f17 100644
--- a/applications/subghz/scenes/subghz_scene_receiver.c
+++ b/applications/subghz/scenes/subghz_scene_receiver.c
@@ -13,7 +13,9 @@ const void subghz_scene_receiver_on_enter(void* context) {
subghz_receiver_set_callback(subghz_receiver, subghz_scene_receiver_callback, subghz);
- subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result);
+ subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result, subghz->protocol);
+ subghz_receiver_set_worker(subghz_receiver, subghz->worker);
+ subghz->state_notifications = NOTIFICATION_RX_STATE;
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver);
}
@@ -21,12 +23,53 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event
SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == SubghzReceverEventSave) {
+ switch(event.event) {
+ case SubghzReceverEventSave:
+ subghz->state_notifications = NOTIFICATION_IDLE_STATE;
+ subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver);
+ subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver);
+ subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
return true;
- } else if(event.event == SubghzReceverEventBack) {
+ break;
+ case SubghzReceverEventBack:
scene_manager_previous_scene(subghz->scene_manager);
return true;
+ break;
+ case SubghzReceverEventSendStart:
+ subghz->state_notifications = NOTIFICATION_TX_STATE;
+ subghz->frequency = subghz_receiver_get_frequency(subghz->subghz_receiver);
+ subghz->preset = subghz_receiver_get_preset(subghz->subghz_receiver);
+ subghz->protocol_result = subghz_receiver_get_protocol(subghz->subghz_receiver);
+ subghz_transmitter_tx_start(subghz);
+ return true;
+ break;
+ case SubghzReceverEventSendStop:
+ subghz->state_notifications = NOTIFICATION_IDLE_STATE;
+ subghz_transmitter_tx_stop(subghz);
+ return true;
+ break;
+ case SubghzReceverEventMain:
+ subghz->state_notifications = NOTIFICATION_RX_STATE;
+ return true;
+ break;
+ case SubghzReceverEventConfig:
+ subghz->state_notifications = NOTIFICATION_IDLE_STATE;
+ return true;
+ break;
+ default:
+ break;
+ }
+ } else if(event.type == SceneManagerEventTypeTick) {
+ switch(subghz->state_notifications) {
+ case NOTIFICATION_TX_STATE:
+ notification_message(subghz->notifications, &sequence_blink_red_10);
+ break;
+ case NOTIFICATION_RX_STATE:
+ notification_message(subghz->notifications, &sequence_blink_blue_10);
+ break;
+ default:
+ break;
}
}
return false;
diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c
index 5a3452f8..fba0c622 100644
--- a/applications/subghz/scenes/subghz_scene_save_name.c
+++ b/applications/subghz/scenes/subghz_scene_save_name.c
@@ -19,7 +19,7 @@ const void subghz_scene_save_name_on_enter(void* context) {
set_random_name(subghz->text_store, sizeof(subghz->text_store));
dev_name_empty = true;
- text_input_set_header_text(text_input, "Name the KEY");
+ text_input_set_header_text(text_input, "Name signal");
text_input_set_result_callback(
text_input,
subghz_scene_save_name_text_input_callback,
diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c
index 09b7a4ac..3bfec82a 100644
--- a/applications/subghz/scenes/subghz_scene_saved.c
+++ b/applications/subghz/scenes/subghz_scene_saved.c
@@ -3,7 +3,7 @@
const void subghz_scene_saved_on_enter(void* context) {
SubGhz* subghz = context;
- if(subghz_saved_protocol_select(subghz)) {
+ if(subghz_load_protocol_from_file(subghz)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter);
} else {
scene_manager_search_and_switch_to_previous_scene(subghz->scene_manager, SubGhzSceneStart);
diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c
index d3c36f54..8948f06e 100644
--- a/applications/subghz/scenes/subghz_scene_set_type.c
+++ b/applications/subghz/scenes/subghz_scene_set_type.c
@@ -32,31 +32,31 @@ const void subghz_scene_set_type_on_enter(void* context) {
submenu_add_item(
subghz->submenu,
- "Pricenton",
+ "Princeton_433",
SubmenuIndexPricenton,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item(
subghz->submenu,
- "Nice Flo 12bit",
+ "Nice Flo 12bit_433",
SubmenuIndexNiceFlo12bit,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item(
subghz->submenu,
- "Nice Flo 24bit",
+ "Nice Flo 24bit_433",
SubmenuIndexNiceFlo24bit,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item(
subghz->submenu,
- "CAME 12bit",
+ "CAME 12bit_433",
SubmenuIndexCAME12bit,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item(
subghz->submenu,
- "CAME 24bit",
+ "CAME 24bit_433",
SubmenuIndexCAME24bit,
subghz_scene_set_type_submenu_callback,
subghz);
@@ -64,13 +64,13 @@ const void subghz_scene_set_type_on_enter(void* context) {
// subghz->submenu, "Nero Sketch", SubmenuIndexNeroSketch, subghz_scene_set_type_submenu_callback, subghz);
submenu_add_item(
subghz->submenu,
- "Gate TX",
+ "Gate TX_433",
SubmenuIndexGateTX,
subghz_scene_set_type_submenu_callback,
subghz);
submenu_add_item(
subghz->submenu,
- "DoorHan",
+ "DoorHan_433",
SubmenuIndexDoorHan,
subghz_scene_set_type_submenu_callback,
subghz);
@@ -159,6 +159,8 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event
break;
}
if(generated_protocol) {
+ subghz->frequency = subghz_frequencies[subghz_frequencies_433_92];
+ subghz->preset = FuriHalSubGhzPresetOok650Async;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
return true;
}
diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c
index d30536a5..64e50d6a 100644
--- a/applications/subghz/scenes/subghz_scene_start.c
+++ b/applications/subghz/scenes/subghz_scene_start.c
@@ -56,9 +56,12 @@ const bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneAnalyze);
return true;
} else if(event.event == SubmenuIndexRead) {
+ // scene_manager_set_scene_state(
+ // subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
+ // scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRead);
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead);
- scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRead);
+ scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
return true;
} else if(event.event == SubmenuIndexSaved) {
scene_manager_set_scene_state(
diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c
index e28e6d88..3ce3ad2d 100644
--- a/applications/subghz/scenes/subghz_scene_transmitter.c
+++ b/applications/subghz/scenes/subghz_scene_transmitter.c
@@ -13,6 +13,7 @@ const void subghz_scene_transmitter_on_enter(void* context) {
subghz_transmitter_set_callback(subghz_transmitter, subghz_scene_transmitter_callback, subghz);
subghz_transmitter_set_protocol(subghz_transmitter, subghz->protocol_result);
+ subghz_transmitter_set_frequency_preset(subghz_transmitter, subghz->frequency, subghz->preset);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter);
@@ -30,6 +31,7 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev
} else if(event.event == SubghzTransmitterEventSendStop) {
subghz->state_notifications = NOTIFICATION_IDLE_STATE;
subghz_transmitter_tx_stop(subghz);
+ subghz_sleep();
return true;
} else if(event.event == SubghzTransmitterEventBack) {
subghz->state_notifications = NOTIFICATION_IDLE_STATE;
diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c
index 0e4eb7fe..3031fec1 100644
--- a/applications/subghz/subghz_cli.c
+++ b/applications/subghz/subghz_cli.c
@@ -42,7 +42,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) {
}
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
@@ -79,7 +79,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) {
}
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
printf("Receiving at frequency %lu Hz\r\n", frequency);
printf("Press CTRL+C to stop\r\n");
@@ -134,12 +134,12 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) {
protocol->common.code_last_found = key;
protocol->common.code_last_count_bit = 24;
- SubGhzProtocolEncoderCommon* encoder = subghz_protocol_encoder_common_alloc();
+ SubGhzProtocolCommonEncoder* encoder = subghz_protocol_encoder_common_alloc();
encoder->repeat = repeat;
subghz_protocol_princeton_send_key(protocol, encoder);
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, encoder);
@@ -212,7 +212,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) {
// Configure radio
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c
new file mode 100644
index 00000000..1aacdea6
--- /dev/null
+++ b/applications/subghz/subghz_history.c
@@ -0,0 +1,155 @@
+#include "subghz_history.h"
+#include <lib/subghz/protocols/subghz_protocol_keeloq.h>
+#include <lib/subghz/protocols/subghz_protocol_star_line.h>
+#include <lib/subghz/protocols/subghz_protocol_princeton.h>
+
+#include <furi.h>
+#include <m-string.h>
+
+#define SUBGHZ_HISTORY_MAX 20
+
+typedef struct SubGhzHistoryStruct SubGhzHistoryStruct;
+
+struct SubGhzHistoryStruct {
+ const char* name;
+ const char* manufacture_name;
+ uint8_t type_protocol;
+ uint8_t code_count_bit;
+ uint64_t code_found;
+ uint16_t te;
+ FuriHalSubGhzPreset preset;
+ uint32_t real_frequency;
+};
+
+struct SubGhzHistory {
+ uint32_t last_update_timestamp;
+ uint16_t last_index_write;
+ uint64_t code_last_found;
+ SubGhzHistoryStruct history[SUBGHZ_HISTORY_MAX];
+ SubGhzProtocolCommonLoad data;
+};
+
+SubGhzHistory* subghz_history_alloc(void) {
+ SubGhzHistory* instance = furi_alloc(sizeof(SubGhzHistory));
+ return instance;
+}
+
+void subghz_history_free(SubGhzHistory* instance) {
+ furi_assert(instance);
+ free(instance);
+}
+
+void subghz_history_set_frequency_preset(
+ SubGhzHistory* instance,
+ uint16_t idx,
+ uint32_t frequency,
+ FuriHalSubGhzPreset preset) {
+ furi_assert(instance);
+ if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return;
+ instance->history[idx].preset = preset;
+ instance->history[idx].real_frequency = frequency;
+}
+
+uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx) {
+ furi_assert(instance);
+ return instance->history[idx].real_frequency;
+}
+
+FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) {
+ furi_assert(instance);
+ return instance->history[idx].preset;
+}
+
+void subghz_history_clean(SubGhzHistory* instance) {
+ furi_assert(instance);
+ instance->last_index_write = 0;
+ instance->code_last_found = 0;
+}
+
+uint16_t subghz_history_get_item(SubGhzHistory* instance) {
+ furi_assert(instance);
+ return instance->last_index_write;
+}
+
+uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx) {
+ furi_assert(instance);
+ return instance->history[idx].type_protocol;
+}
+
+const char* subghz_history_get_name(SubGhzHistory* instance, uint16_t idx) {
+ furi_assert(instance);
+ return instance->history[idx].name;
+}
+
+SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) {
+ furi_assert(instance);
+ instance->data.code_found = instance->history[idx].code_found;
+ instance->data.code_count_bit = instance->history[idx].code_count_bit;
+ instance->data.param1 = instance->history[idx].te;
+ return &instance->data;
+}
+
+void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx) {
+ if(instance->history[idx].code_count_bit < 33) {
+ string_printf(
+ output,
+ "%s %lX",
+ instance->history[idx].name,
+ (uint32_t)(instance->history[idx].code_found & 0xFFFFFFFF));
+ } else {
+ string_t str_buff;
+ string_init(str_buff);
+ if(strcmp(instance->history[idx].name, "KeeLoq") == 0) {
+ string_set(str_buff, "KL ");
+ string_cat(str_buff, instance->history[idx].manufacture_name);
+ } else if(strcmp(instance->history[idx].name, "Star Line") == 0) {
+ string_set(str_buff, "SL ");
+ string_cat(str_buff, instance->history[idx].manufacture_name);
+ } else {
+ string_set(str_buff, instance->history[idx].name);
+ }
+
+ string_printf(
+ output,
+ "%s %lX%08lX",
+ string_get_cstr(str_buff),
+ (uint32_t)(instance->history[idx].code_found >> 32),
+ (uint32_t)(instance->history[idx].code_found & 0xFFFFFFFF));
+ string_clear(str_buff);
+ }
+}
+
+void subghz_history_add_to_history(SubGhzHistory* instance, void* context) {
+ furi_assert(instance);
+ furi_assert(context);
+ SubGhzProtocolCommon* protocol = context;
+
+ if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return;
+ if((instance->code_last_found == (protocol->code_last_found & 0xFFFF0FFFFFFFFFFF)) &&
+ ((millis() - instance->last_update_timestamp) < 500)) {
+ instance->last_update_timestamp = millis();
+ return;
+ }
+
+ instance->code_last_found = protocol->code_last_found & 0xFFFF0FFFFFFFFFFF;
+ instance->last_update_timestamp = millis();
+
+ instance->history[instance->last_index_write].te = 0;
+ instance->history[instance->last_index_write].manufacture_name = NULL;
+ instance->history[instance->last_index_write].name = protocol->name;
+ instance->history[instance->last_index_write].code_count_bit = protocol->code_last_count_bit;
+ instance->history[instance->last_index_write].code_found = protocol->code_last_found;
+ if(strcmp(protocol->name, "KeeLoq") == 0) {
+ instance->history[instance->last_index_write].manufacture_name =
+ subghz_protocol_keeloq_get_manufacture_name(protocol);
+ } else if(strcmp(protocol->name, "Star Line") == 0) {
+ instance->history[instance->last_index_write].manufacture_name =
+ subghz_protocol_star_line_get_manufacture_name(protocol);
+ } else if(strcmp(protocol->name, "Princeton") == 0) {
+ instance->history[instance->last_index_write].te =
+ subghz_protocol_princeton_get_te(protocol);
+ }
+ instance->history[instance->last_index_write].type_protocol = protocol->type_protocol;
+
+ instance->last_index_write++;
+} \ No newline at end of file
diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h
new file mode 100644
index 00000000..a0964fa0
--- /dev/null
+++ b/applications/subghz/subghz_history.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <lib/subghz/protocols/subghz_protocol_common.h>
+
+typedef struct SubGhzHistory SubGhzHistory;
+
+SubGhzHistory* subghz_history_alloc(void);
+void subghz_history_free(SubGhzHistory* instance);
+void subghz_history_clean(SubGhzHistory* instance);
+void subghz_history_set_frequency_preset(
+ SubGhzHistory* instance,
+ uint16_t idx,
+ uint32_t frequency,
+ FuriHalSubGhzPreset preset);
+uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx);
+FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx);
+uint16_t subghz_history_get_item(SubGhzHistory* instance);
+uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx);
+const char* subghz_history_get_name(SubGhzHistory* instance, uint16_t idx);
+void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx);
+void subghz_history_add_to_history(SubGhzHistory* instance, void* context);
+SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx);
diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c
index 03ebbc26..a339edfb 100644
--- a/applications/subghz/subghz_i.c
+++ b/applications/subghz/subghz_i.c
@@ -8,6 +8,7 @@
#include <notification/notification-messages.h>
#include "file-worker.h"
#include "../notification/notification.h"
+#include "views/subghz_receiver.h"
void subghz_begin(FuriHalSubGhzPreset preset) {
furi_hal_subghz_reset();
@@ -16,30 +17,59 @@ void subghz_begin(FuriHalSubGhzPreset preset) {
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
}
-void subghz_rx(uint32_t frequency) {
+uint32_t subghz_rx(void* context, uint32_t frequency) {
+ furi_assert(context);
+ SubGhzWorker* worker = context;
+
furi_hal_subghz_idle();
- furi_hal_subghz_set_frequency_and_path(frequency);
+ uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
furi_hal_subghz_flush_rx();
furi_hal_subghz_rx();
+
+ furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, worker);
+ subghz_worker_start(worker);
+ return value;
}
-void subghz_tx(uint32_t frequency) {
+uint32_t subghz_tx(uint32_t frequency) {
furi_hal_subghz_idle();
- furi_hal_subghz_set_frequency_and_path(frequency);
+ uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
hal_gpio_write(&gpio_cc1101_g0, true);
furi_hal_subghz_tx();
+ return value;
}
void subghz_idle(void) {
furi_hal_subghz_idle();
}
-void subghz_end(void) {
+void subghz_rx_end(void* context) {
+ furi_assert(context);
+ SubGhzWorker* worker = context;
+
+ if(subghz_worker_is_running(worker)) {
+ subghz_worker_stop(worker);
+ furi_hal_subghz_stop_async_rx();
+ }
+}
+
+void subghz_sleep(void) {
furi_hal_subghz_sleep();
}
+void subghz_frequency_preset_to_str(void* context, string_t output) {
+ furi_assert(context);
+ SubGhz* subghz = context;
+ string_cat_printf(
+ output,
+ "Frequency: %d\n"
+ "Preset: %d\n",
+ (int)subghz->frequency,
+ (int)subghz->preset);
+}
+
void subghz_transmitter_tx_start(void* context) {
SubGhz* subghz = context;
subghz->encoder = subghz_protocol_encoder_common_alloc();
@@ -47,8 +77,17 @@ void subghz_transmitter_tx_start(void* context) {
//get upload
if(subghz->protocol_result->get_upload_protocol) {
if(subghz->protocol_result->get_upload_protocol(subghz->protocol_result, subghz->encoder)) {
- subghz_begin(FuriHalSubGhzPresetOokAsync);
- subghz_tx(433920000);
+ if(subghz->preset) {
+ subghz_begin(subghz->preset);
+ } else {
+ subghz_begin(FuriHalSubGhzPresetOok650Async);
+ }
+ if(subghz->frequency) {
+ subghz_tx(subghz->frequency);
+ } else {
+ subghz_tx(433920000);
+ }
+
//Start TX
furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, subghz->encoder);
}
@@ -59,7 +98,6 @@ void subghz_transmitter_tx_stop(void* context) {
SubGhz* subghz = context;
//Stop TX
furi_hal_subghz_stop_async_tx();
- subghz_end();
subghz_protocol_encoder_common_free(subghz->encoder);
//if protocol dynamic then we save the last upload
if(subghz->protocol_result->type_protocol == TYPE_PROTOCOL_DYNAMIC) {
@@ -79,12 +117,35 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
string_init_set_str(path, file_path);
string_t temp_str;
string_init(temp_str);
+ int res = 0;
+ int data = 0;
do {
if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
break;
}
- // Read and parse name protocol from 1st line
+
+ // Read and parse frequency from 1st line
+ if(!file_worker_read_until(file_worker, temp_str, '\n')) {
+ break;
+ }
+ res = sscanf(string_get_cstr(temp_str), "Frequency: %d\n", &data);
+ if(res != 1) {
+ break;
+ }
+ subghz->frequency = (uint32_t)data;
+
+ // Read and parse preset from 2st line
+ if(!file_worker_read_until(file_worker, temp_str, '\n')) {
+ break;
+ }
+ res = sscanf(string_get_cstr(temp_str), "Preset: %d\n", &data);
+ if(res != 1) {
+ break;
+ }
+ subghz->preset = (FuriHalSubGhzPreset)data;
+
+ // Read and parse name protocol from 2st line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
@@ -93,16 +154,18 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
subghz->protocol_result =
subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str));
if(subghz->protocol_result == NULL) {
- file_worker_show_error(file_worker, "Cannot parse\nfile");
break;
}
- if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) {
- file_worker_show_error(file_worker, "Cannot parse\nfile");
+ if(!subghz->protocol_result->to_load_protocol_from_file(
+ file_worker, subghz->protocol_result)) {
break;
}
loaded = true;
} while(0);
+ if(!loaded) {
+ file_worker_show_error(file_worker, "Cannot parse\nfile");
+ }
string_clear(temp_str);
string_clear(path);
file_worker_close(file_worker);
@@ -113,6 +176,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
bool subghz_save_protocol_to_file(void* context, const char* dev_name) {
SubGhz* subghz = context;
+ furi_assert(subghz->protocol_result);
FileWorker* file_worker = file_worker_alloc(false);
string_t dev_file_name;
string_init(dev_file_name);
@@ -140,6 +204,11 @@ bool subghz_save_protocol_to_file(void* context, const char* dev_name) {
file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
break;
}
+ //Get string frequency preset protocol
+ subghz_frequency_preset_to_str(subghz, temp_str);
+ if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_size(temp_str))) {
+ break;
+ }
//Get string save
subghz->protocol_result->to_save_string(subghz->protocol_result, temp_str);
// Prepare and write data to file
@@ -157,7 +226,7 @@ bool subghz_save_protocol_to_file(void* context, const char* dev_name) {
return saved;
}
-bool subghz_saved_protocol_select(SubGhz* subghz) {
+bool subghz_load_protocol_from_file(SubGhz* subghz) {
furi_assert(subghz);
FileWorker* file_worker = file_worker_alloc(false);
@@ -165,6 +234,8 @@ bool subghz_saved_protocol_select(SubGhz* subghz) {
string_init(protocol_file_name);
string_t temp_str;
string_init(temp_str);
+ int sscanf_res = 0;
+ int data = 0;
// Input events and views are managed by file_select
bool res = file_worker_file_select(
@@ -197,7 +268,27 @@ bool subghz_saved_protocol_select(SubGhz* subghz) {
file_worker, string_get_cstr(protocol_file_name), FSAM_READ, FSOM_OPEN_EXISTING)) {
break;
}
- // Read and parse name protocol from 1st line
+ // Read and parse frequency from 1st line
+ if(!file_worker_read_until(file_worker, temp_str, '\n')) {
+ break;
+ }
+ sscanf_res = sscanf(string_get_cstr(temp_str), "Frequency: %d\n", &data);
+ if(sscanf_res != 1) {
+ break;
+ }
+ subghz->frequency = (uint32_t)data;
+
+ // Read and parse preset from 2st line
+ if(!file_worker_read_until(file_worker, temp_str, '\n')) {
+ break;
+ }
+ sscanf_res = sscanf(string_get_cstr(temp_str), "Preset: %d\n", &data);
+ if(sscanf_res != 1) {
+ break;
+ }
+ subghz->preset = (FuriHalSubGhzPreset)data;
+
+ // Read and parse name protocol from 3st line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
@@ -206,16 +297,19 @@ bool subghz_saved_protocol_select(SubGhz* subghz) {
subghz->protocol_result =
subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str));
if(subghz->protocol_result == NULL) {
- file_worker_show_error(file_worker, "Cannot parse\nfile");
break;
}
- if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) {
- file_worker_show_error(file_worker, "Cannot parse\nfile");
+ if(!subghz->protocol_result->to_load_protocol_from_file(
+ file_worker, subghz->protocol_result)) {
break;
}
res = true;
} while(0);
+ if(!res) {
+ file_worker_show_error(file_worker, "Cannot parse\nfile");
+ }
+
string_clear(temp_str);
string_clear(protocol_file_name);
diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h
index 8149363d..8b084209 100644
--- a/applications/subghz/subghz_i.h
+++ b/applications/subghz/subghz_i.h
@@ -25,12 +25,14 @@
#include <lib/subghz/subghz_worker.h>
#include <lib/subghz/protocols/subghz_protocol.h>
#include <lib/subghz/protocols/subghz_protocol_common.h>
+#include "subghz_history.h"
#define SUBGHZ_TEXT_STORE_SIZE 128
#define NOTIFICATION_STARTING_STATE 0u
#define NOTIFICATION_IDLE_STATE 1u
#define NOTIFICATION_TX_STATE 2u
+#define NOTIFICATION_RX_STATE 3u
extern const uint32_t subghz_frequencies[];
extern const uint32_t subghz_frequencies_count;
@@ -43,10 +45,11 @@ struct SubGhz {
SubGhzWorker* worker;
SubGhzProtocol* protocol;
SubGhzProtocolCommon* protocol_result;
- SubGhzProtocolEncoderCommon* encoder;
+ SubGhzProtocolCommonEncoder* encoder;
+ uint32_t frequency;
+ FuriHalSubGhzPreset preset;
SceneManager* scene_manager;
-
ViewDispatcher* view_dispatcher;
Submenu* submenu;
@@ -81,13 +84,14 @@ typedef enum {
} SubGhzView;
void subghz_begin(FuriHalSubGhzPreset preset);
-void subghz_rx(uint32_t frequency);
-void subghz_tx(uint32_t frequency);
+uint32_t subghz_rx(void* context, uint32_t frequency);
+uint32_t subghz_tx(uint32_t frequency);
void subghz_idle(void);
-void subghz_end(void);
+void subghz_rx_end(void* context);
+void subghz_sleep(void);
void subghz_transmitter_tx_start(void* context);
void subghz_transmitter_tx_stop(void* context);
bool subghz_key_load(SubGhz* subghz, const char* file_path);
bool subghz_save_protocol_to_file(void* context, const char* dev_name);
-bool subghz_saved_protocol_select(SubGhz* subghz);
+bool subghz_load_protocol_from_file(SubGhz* subghz);
uint32_t subghz_random_serial(void);
diff --git a/applications/subghz/views/subghz_analyze.c b/applications/subghz/views/subghz_analyze.c
index 7380a026..cef72303 100644
--- a/applications/subghz/views/subghz_analyze.c
+++ b/applications/subghz/views/subghz_analyze.c
@@ -58,7 +58,7 @@ void subghz_analyze_draw(Canvas* canvas, SubghzAnalyzeModel* model) {
default:
canvas_set_font(canvas, FontSecondary);
- elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text));
+ elements_multiline_text(canvas, 0, 18, string_get_cstr(model->text));
break;
}
}
@@ -144,7 +144,7 @@ void subghz_analyze_enter(void* context) {
furi_hal_subghz_reset();
furi_hal_subghz_idle();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
with_view_model(
subghz_analyze->view, (SubghzAnalyzeModel * model) {
diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c
index a4d9aef7..147811dc 100644
--- a/applications/subghz/views/subghz_receiver.c
+++ b/applications/subghz/views/subghz_receiver.c
@@ -1,25 +1,55 @@
#include "subghz_receiver.h"
#include "../subghz_i.h"
-
#include <math.h>
#include <furi.h>
#include <furi-hal.h>
#include <input/input.h>
#include <gui/elements.h>
#include <notification/notification-messages.h>
+#include <lib/subghz/protocols/subghz_protocol_princeton.h>
#include <assets_icons.h>
+#define FRAME_HEIGHT 12
+#define MAX_LEN_PX 100
+#define MENU_ITEMS 4
+
+typedef enum {
+ ReceiverSceneStart,
+ ReceiverSceneMain,
+ ReceiverSceneConfig,
+ ReceiverSceneInfo,
+} SubghzReceiverScene;
+
+static const Icon* ReceiverItemIcons[] = {
+ [TYPE_PROTOCOL_UNKNOWN] = &I_quest_7x8,
+ [TYPE_PROTOCOL_STATIC] = &I_unlock_7x8,
+ [TYPE_PROTOCOL_DYNAMIC] = &I_lock_7x8,
+};
+
struct SubghzReceiver {
View* view;
SubghzReceiverCallback callback;
void* context;
+ SubGhzWorker* worker;
+ SubGhzProtocol* protocol;
};
typedef struct {
string_t text;
uint16_t scene;
- SubGhzProtocolCommon* protocol;
+ SubGhzProtocolCommon* protocol_result;
+ SubGhzHistory* history;
+ uint8_t frequency;
+ uint8_t temp_frequency;
+ uint32_t real_frequency;
+
+ uint8_t tab_idx;
+ uint8_t menu_idx;
+ uint16_t idx;
+ uint16_t list_offset;
+ uint16_t history_item;
+ bool menu;
} SubghzReceiverModel;
void subghz_receiver_set_callback(
@@ -32,50 +62,323 @@ void subghz_receiver_set_callback(
subghz_receiver->context = context;
}
-void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol) {
+void subghz_receiver_set_protocol(
+ SubghzReceiver* subghz_receiver,
+ SubGhzProtocolCommon* protocol_result,
+ SubGhzProtocol* protocol) {
+ furi_assert(subghz_receiver);
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
- model->protocol = protocol;
+ model->protocol_result = protocol_result;
return true;
});
+ subghz_receiver->protocol = protocol;
+}
+
+SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver) {
+ furi_assert(subghz_receiver);
+ SubGhzProtocolCommon* result = NULL;
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ result = model->protocol_result;
+ return false;
+ });
+ return result;
+}
+
+void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker) {
+ furi_assert(subghz_receiver);
+ subghz_receiver->worker = worker;
+}
+
+static void subghz_receiver_update_offset(SubghzReceiver* subghz_receiver) {
+ furi_assert(subghz_receiver);
+
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ size_t history_item = model->history_item;
+ uint16_t bounds = history_item > 3 ? 2 : history_item;
+
+ if(history_item > 3 && model->idx >= history_item - 1) {
+ model->list_offset = model->idx - 3;
+ } else if(model->list_offset < model->idx - bounds) {
+ model->list_offset = CLAMP(model->list_offset + 1, history_item - bounds, 0);
+ } else if(model->list_offset > model->idx - bounds) {
+ model->list_offset = CLAMP(model->idx - 1, history_item - bounds, 0);
+ }
+ return true;
+ });
+}
+
+static void subghz_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) {
+ canvas_set_color(canvas, ColorBlack);
+ canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT);
+
+ canvas_set_color(canvas, ColorWhite);
+ canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT);
+ canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT);
+ canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1);
+
+ canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11);
+ canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT);
+ canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11);
}
void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
+ bool scrollbar = model->history_item > 4;
+ string_t str_buff;
+ char buffer[64];
+ string_init(str_buff);
+
canvas_clear(canvas);
canvas_set_color(canvas, ColorBlack);
- canvas_set_font(canvas, FontSecondary);
- elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text));
- elements_button_left(canvas, "Back");
- if(model->protocol && model->protocol->to_save_string &&
- strcmp(model->protocol->name, "KeeLoq")) {
- elements_button_right(canvas, "Save");
+ switch(model->scene) {
+ case ReceiverSceneMain:
+ for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) {
+ size_t idx = CLAMP(i + model->list_offset, model->history_item, 0);
+ subghz_history_get_text_item_menu(model->history, str_buff, idx);
+ elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX);
+ if(model->idx == idx) {
+ subghz_receiver_draw_frame(canvas, i, scrollbar);
+ } else {
+ canvas_set_color(canvas, ColorBlack);
+ }
+ canvas_draw_icon(
+ canvas,
+ 1,
+ 2 + i * FRAME_HEIGHT,
+ ReceiverItemIcons[subghz_history_get_type_protocol(model->history, idx)]);
+ canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, string_get_cstr(str_buff));
+ string_clean(str_buff);
+ }
+ if(scrollbar) {
+ elements_scrollbar_pos(canvas, 126, 0, 49, model->idx, model->history_item);
+ }
+ canvas_set_color(canvas, ColorBlack);
+ canvas_set_font(canvas, FontPrimary);
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%03ld.%03ld OOK",
+ model->real_frequency / 1000000 % 1000,
+ model->real_frequency / 1000 % 1000);
+ canvas_draw_str(canvas, 60, 61, buffer);
+ elements_button_left(canvas, "Config");
+ break;
+
+ case ReceiverSceneStart:
+ canvas_draw_icon(canvas, 0, 0, &I_RFIDDolphinReceive_97x61);
+ canvas_invert_color(canvas);
+ canvas_draw_box(canvas, 80, 2, 20, 20);
+ canvas_invert_color(canvas);
+ canvas_draw_icon(canvas, 75, 8, &I_sub1_10px);
+ canvas_set_font(canvas, FontPrimary);
+ canvas_draw_str(canvas, 63, 40, "Scanning...");
+ canvas_set_color(canvas, ColorBlack);
+ canvas_set_font(canvas, FontPrimary);
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%03ld.%03ld OOK",
+ model->real_frequency / 1000000 % 1000,
+ model->real_frequency / 1000 % 1000);
+ canvas_draw_str(canvas, 60, 61, buffer);
+ elements_button_left(canvas, "Config");
+ break;
+
+ case ReceiverSceneConfig:
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "Frequency: < %03ld.%03ldMHz >",
+ model->real_frequency / 1000000 % 1000,
+ model->real_frequency / 1000 % 1000);
+ canvas_draw_str(canvas, 0, 8, buffer);
+ elements_button_center(canvas, "Save");
+ break;
+
+ case ReceiverSceneInfo:
+ canvas_set_font(canvas, FontSecondary);
+ elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text));
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%03ld.%03ld",
+ subghz_history_get_frequency(model->history, model->idx) / 1000000 % 1000,
+ subghz_history_get_frequency(model->history, model->idx) / 1000 % 1000);
+ canvas_draw_str(canvas, 90, 8, buffer);
+ if(model->protocol_result && model->protocol_result->to_save_string &&
+ strcmp(model->protocol_result->name, "KeeLoq")) {
+ elements_button_right(canvas, "Save");
+ elements_button_center(canvas, "Send");
+ }
+ break;
+
+ default:
+
+ break;
}
+
+ string_clear(str_buff);
}
bool subghz_receiver_input(InputEvent* event, void* context) {
furi_assert(context);
- SubghzReceiver* subghz_receiver = context;
- if(event->type != InputTypeShort) return false;
-
- bool can_be_saved = false;
+ uint8_t scene = 0;
+ SubghzReceiver* subghz_receiver = context;
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
- can_be_saved =
- (model->protocol && model->protocol->to_save_string &&
- strcmp(model->protocol->name, "KeeLoq"));
+ scene = model->scene;
return false;
});
- if(event->key == InputKeyBack) {
- return false;
- } else if(event->key == InputKeyLeft) {
- subghz_receiver->callback(SubghzReceverEventBack, subghz_receiver->context);
- } else if(can_be_saved && event->key == InputKeyRight) {
- subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
+ if(scene != ReceiverSceneInfo && event->type != InputTypeShort) return false;
+
+ bool can_be_saved = false;
+
+ switch(scene) {
+ case ReceiverSceneMain:
+ if(event->key == InputKeyBack) {
+ return false;
+ } else if(event->key == InputKeyUp) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ if(model->idx != 0) model->idx--;
+ return true;
+ });
+ } else if(event->key == InputKeyDown) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ if(model->idx != subghz_history_get_item(model->history) - 1) model->idx++;
+ return true;
+ });
+ } else if(event->key == InputKeyLeft) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ model->scene = ReceiverSceneConfig;
+ model->temp_frequency = model->frequency;
+ return true;
+ });
+ subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
+ } else if(event->key == InputKeyOk) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ string_clean(model->text);
+ model->protocol_result = subghz_protocol_get_by_name(
+ subghz_receiver->protocol,
+ subghz_history_get_name(model->history, model->idx));
+ if(model->protocol_result->to_load_protocol != NULL) {
+ model->protocol_result->to_load_protocol(
+ model->protocol_result,
+ subghz_history_get_raw_data(model->history, model->idx));
+ model->protocol_result->to_string(model->protocol_result, model->text);
+ model->scene = ReceiverSceneInfo;
+ }
+ return true;
+ });
+ }
+ break;
+
+ case ReceiverSceneInfo:
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ can_be_saved =
+ (model->protocol_result && model->protocol_result->to_save_string &&
+ strcmp(model->protocol_result->name, "KeeLoq"));
+ return false;
+ });
+ if(event->key == InputKeyBack && event->type == InputTypeShort) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ subghz_rx_end(subghz_receiver->worker);
+ model->real_frequency =
+ subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
+ model->scene = ReceiverSceneMain;
+ return true;
+ });
+ subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
+ } else if(can_be_saved && event->key == InputKeyRight) {
+ subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
+ return false;
+ } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypePress) {
+ subghz_rx_end(subghz_receiver->worker);
+ subghz_receiver->callback(SubghzReceverEventSendStart, subghz_receiver->context);
+ return true;
+ } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease) {
+ subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context);
+ return true;
+ }
+ break;
+
+ case ReceiverSceneConfig:
+ if(event->key == InputKeyBack) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ model->frequency = model->temp_frequency;
+ model->real_frequency = subghz_frequencies[model->frequency];
+ if(subghz_history_get_item(model->history) == 0) {
+ model->scene = ReceiverSceneStart;
+ } else {
+ model->scene = ReceiverSceneMain;
+ }
+ return true;
+ });
+ subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
+ } else if(event->key == InputKeyOk) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ subghz_rx_end(subghz_receiver->worker);
+ model->real_frequency =
+ subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
+ if(subghz_history_get_item(model->history) == 0) {
+ model->scene = ReceiverSceneStart;
+ } else {
+ model->scene = ReceiverSceneMain;
+ }
+ return true;
+ });
+ subghz_receiver->callback(SubghzReceverEventMain, subghz_receiver->context);
+ } else {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ bool model_updated = false;
+
+ if(event->key == InputKeyLeft) {
+ if(model->frequency > 0) model->frequency--;
+ model_updated = true;
+ } else if(event->key == InputKeyRight) {
+ if(model->frequency < subghz_frequencies_count - 1) model->frequency++;
+ model_updated = true;
+ }
+ if(model_updated) {
+ model->real_frequency = subghz_frequencies[model->frequency];
+ }
+ return model_updated;
+ });
+ }
+ break;
+
+ case ReceiverSceneStart:
+ if(event->key == InputKeyBack) {
+ return false;
+ } else if(event->key == InputKeyLeft) {
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ model->temp_frequency = model->frequency;
+ model->scene = ReceiverSceneConfig;
+ return true;
+ });
+ subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
+ }
+ break;
+
+ default:
+ break;
}
+ subghz_receiver_update_offset(subghz_receiver);
return true;
}
@@ -86,19 +389,53 @@ void subghz_receiver_text_callback(string_t text, void* context) {
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
string_set(model->text, text);
- model->scene = 0;
+ model->scene = ReceiverSceneMain;
return true;
});
}
+void subghz_receiver_protocol_callback(SubGhzProtocolCommon* parser, void* context) {
+ furi_assert(context);
+ SubghzReceiver* subghz_receiver = context;
+
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ model->protocol_result = parser;
+ subghz_history_set_frequency_preset(
+ model->history,
+ model->history_item,
+ model->real_frequency,
+ FuriHalSubGhzPresetOok650Async);
+ subghz_history_add_to_history(model->history, parser);
+
+ model->history_item = subghz_history_get_item(model->history);
+ model->scene = ReceiverSceneMain;
+ return true;
+ });
+ subghz_protocol_reset(subghz_receiver->protocol);
+ subghz_receiver_update_offset(subghz_receiver);
+}
+
void subghz_receiver_enter(void* context) {
furi_assert(context);
SubghzReceiver* subghz_receiver = context;
+ //Start CC1101 Rx
+ subghz_begin(FuriHalSubGhzPresetOok650Async);
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
- model->protocol->to_string(model->protocol, model->text);
+ subghz_rx_end(subghz_receiver->worker);
+ model->frequency = subghz_frequencies_433_92;
+ model->real_frequency =
+ subghz_rx(subghz_receiver->worker, subghz_frequencies[model->frequency]);
+ if(subghz_history_get_item(model->history) == 0) {
+ model->scene = ReceiverSceneStart;
+ } else {
+ model->scene = ReceiverSceneMain;
+ }
return true;
});
+ subghz_protocol_enable_dump(
+ subghz_receiver->protocol, subghz_receiver_protocol_callback, subghz_receiver);
}
void subghz_receiver_exit(void* context) {
@@ -109,6 +446,9 @@ void subghz_receiver_exit(void* context) {
string_clean(model->text);
return true;
});
+ // Stop CC1101 Rx
+ subghz_rx_end(subghz_receiver->worker);
+ subghz_sleep();
}
SubghzReceiver* subghz_receiver_alloc() {
@@ -126,6 +466,7 @@ SubghzReceiver* subghz_receiver_alloc() {
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
string_init(model->text);
+ model->history = subghz_history_alloc();
return true;
});
return subghz_receiver;
@@ -137,7 +478,8 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver) {
with_view_model(
subghz_receiver->view, (SubghzReceiverModel * model) {
string_clear(model->text);
- return true;
+ subghz_history_free(model->history);
+ return false;
});
view_free(subghz_receiver->view);
free(subghz_receiver);
@@ -147,3 +489,44 @@ View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver) {
furi_assert(subghz_receiver);
return subghz_receiver->view;
}
+
+uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver) {
+ furi_assert(subghz_receiver);
+ uint32_t frequency;
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ frequency = subghz_history_get_frequency(model->history, model->idx);
+ return false;
+ });
+ return frequency;
+}
+
+FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver) {
+ furi_assert(subghz_receiver);
+ FuriHalSubGhzPreset preset;
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ preset = subghz_history_get_preset(model->history, model->idx);
+ return false;
+ });
+ return preset;
+}
+
+void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output) {
+ furi_assert(subghz_receiver);
+ uint32_t frequency;
+ uint32_t preset;
+ with_view_model(
+ subghz_receiver->view, (SubghzReceiverModel * model) {
+ frequency = subghz_history_get_frequency(model->history, model->idx);
+ preset = (uint32_t)subghz_history_get_preset(model->history, model->idx);
+ return false;
+ });
+
+ string_cat_printf(
+ output,
+ "Frequency: %d\n"
+ "Preset: %d\n",
+ (int)frequency,
+ (int)preset);
+} \ No newline at end of file
diff --git a/applications/subghz/views/subghz_receiver.h b/applications/subghz/views/subghz_receiver.h
index 924f90b8..b4aa7bbc 100644
--- a/applications/subghz/views/subghz_receiver.h
+++ b/applications/subghz/views/subghz_receiver.h
@@ -2,10 +2,19 @@
#include <gui/view.h>
#include <lib/subghz/protocols/subghz_protocol_common.h>
+#include <lib/subghz/protocols/subghz_protocol.h>
+#include <lib/subghz/subghz_worker.h>
+#include "../subghz_history.h"
typedef enum {
+ SubghzReceverEventOK,
+ SubghzReceverEventConfig,
+ SubghzReceverEventMain,
SubghzReceverEventSave,
SubghzReceverEventBack,
+ SubghzReceverEventMore,
+ SubghzReceverEventSendStart,
+ SubghzReceverEventSendStop
} SubghzReceverEvent;
typedef struct SubghzReceiver SubghzReceiver;
@@ -23,4 +32,12 @@ void subghz_receiver_free(SubghzReceiver* subghz_receiver);
View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver);
-void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol);
+void subghz_receiver_set_protocol(
+ SubghzReceiver* subghz_receiver,
+ SubGhzProtocolCommon* protocol_result,
+ SubGhzProtocol* protocol);
+SubGhzProtocolCommon* subghz_receiver_get_protocol(SubghzReceiver* subghz_receiver);
+void subghz_receiver_set_worker(SubghzReceiver* subghz_receiver, SubGhzWorker* worker);
+uint32_t subghz_receiver_get_frequency(SubghzReceiver* subghz_receiver);
+FuriHalSubGhzPreset subghz_receiver_get_preset(SubghzReceiver* subghz_receiver);
+void subghz_receiver_frequency_preset_to_str(SubghzReceiver* subghz_receiver, string_t output);
diff --git a/applications/subghz/views/subghz_static.c b/applications/subghz/views/subghz_static.c
index 25c9b9b4..bdb11753 100644
--- a/applications/subghz/views/subghz_static.c
+++ b/applications/subghz/views/subghz_static.c
@@ -112,7 +112,7 @@ void subghz_static_enter(void* context) {
SubghzStatic* instance = context;
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
hal_gpio_write(&gpio_cc1101_g0, false);
diff --git a/applications/subghz/views/subghz_test_carrier.c b/applications/subghz/views/subghz_test_carrier.c
index acd1dacb..82d11650 100644
--- a/applications/subghz/views/subghz_test_carrier.c
+++ b/applications/subghz/views/subghz_test_carrier.c
@@ -119,7 +119,7 @@ void subghz_test_carrier_enter(void* context) {
SubghzTestCarrier* subghz_test_carrier = context;
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c
index 66a8eeee..f1c48179 100644
--- a/applications/subghz/views/subghz_test_packet.c
+++ b/applications/subghz/views/subghz_test_packet.c
@@ -166,7 +166,7 @@ void subghz_test_packet_enter(void* context) {
SubghzTestPacket* instance = context;
furi_hal_subghz_reset();
- furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync);
+ furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
with_view_model(
instance->view, (SubghzTestPacketModel * model) {
diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c
index 1ba76d97..efa35fde 100644
--- a/applications/subghz/views/subghz_transmitter.c
+++ b/applications/subghz/views/subghz_transmitter.c
@@ -8,7 +8,8 @@
#include <gui/elements.h>
#include <notification/notification-messages.h>
-#include <assets_icons.h>
+//#include <assets_icons.h>
+#include <gui/icon_i.h>
struct SubghzTransmitter {
View* view;
@@ -19,6 +20,8 @@ struct SubghzTransmitter {
typedef struct {
string_t text;
uint16_t scene;
+ uint32_t real_frequency;
+ FuriHalSubGhzPreset preset;
SubGhzProtocolCommon* protocol;
} SubghzTransmitterModel;
@@ -42,14 +45,65 @@ void subghz_transmitter_set_protocol(
});
}
+void subghz_transmitter_set_frequency_preset(
+ SubghzTransmitter* subghz_transmitter,
+ uint32_t frequency,
+ FuriHalSubGhzPreset preset) {
+ with_view_model(
+ subghz_transmitter->view, (SubghzTransmitterModel * model) {
+ model->real_frequency = frequency;
+ model->preset = preset;
+ return true;
+ });
+}
+
+static void subghz_transmitter_button_right(Canvas* canvas, const char* str) {
+ const uint8_t button_height = 13;
+ const uint8_t vertical_offset = 3;
+ const uint8_t horizontal_offset = 1;
+ const uint8_t string_width = canvas_string_width(canvas, str);
+ const Icon* icon = &I_ButtonCenter_7x7;
+ const uint8_t icon_offset = 3;
+ const uint8_t icon_width_with_offset = icon->width + icon_offset;
+ const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+
+ const uint8_t x = (canvas_width(canvas) - button_width) / 2 + 40;
+ const uint8_t y = canvas_height(canvas);
+
+ canvas_draw_box(canvas, x, y - button_height, button_width, button_height);
+
+ canvas_draw_line(canvas, x - 1, y, x - 1, y - button_height + 0);
+ canvas_draw_line(canvas, x - 2, y, x - 2, y - button_height + 1);
+ canvas_draw_line(canvas, x - 3, y, x - 3, y - button_height + 2);
+
+ canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y - button_height + 0);
+ canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y - button_height + 1);
+ canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
+
+ canvas_invert_color(canvas);
+ canvas_draw_icon(
+ canvas, x + horizontal_offset, y - button_height + vertical_offset, &I_ButtonCenter_7x7);
+ canvas_draw_str(
+ canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
+ canvas_invert_color(canvas);
+}
+
void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) {
+ char buffer[64];
canvas_clear(canvas);
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontSecondary);
- elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text));
+ elements_multiline_text(canvas, 0, 8, string_get_cstr(model->text));
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%03ld.%03ld",
+ model->real_frequency / 1000000 % 1000,
+ model->real_frequency / 1000 % 1000);
+ canvas_draw_str(canvas, 90, 8, buffer);
if(model->protocol && model->protocol->get_upload_protocol) {
- elements_button_center(canvas, "Send");
+ subghz_transmitter_button_right(canvas, "Send");
}
}
diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h
index 2c1f1b72..6f289e4d 100644
--- a/applications/subghz/views/subghz_transmitter.h
+++ b/applications/subghz/views/subghz_transmitter.h
@@ -27,3 +27,7 @@ View* subghz_transmitter_get_view(SubghzTransmitter* subghz_transmitter);
void subghz_transmitter_set_protocol(
SubghzTransmitter* subghz_transmitter,
SubGhzProtocolCommon* protocol);
+void subghz_transmitter_set_frequency_preset(
+ SubghzTransmitter* subghz_transmitter,
+ uint32_t frequency,
+ FuriHalSubGhzPreset preset);