diff options
author | Skorpionm <85568270+Skorpionm@users.noreply.github.com> | 2021-10-25 17:37:14 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-25 17:37:14 +0300 |
commit | 9d952ed855af306686625f7c5714319c4d906bec (patch) | |
tree | 9da0f13d4d1e84f70e545931a0bd078d8cd85971 /applications/subghz/views | |
parent | 88cee4601ace0088085b3b07ba17b78315cae52b (diff) |
[FL-1913, FL-1963] SubGhz: save raw signal, add came atomo decoder (#783)
* File_Worker: getting the name of a new file with an index
* SubGhz: add decoder RAW protocol
* SubGhz: add view Save RAW
* SubGhz: refactoring subghz custom event
* SubGhz: fix syntax
* SubGhz: fix error build
* SubGhz: test build
* SubGhz: refactoring subghz, add rename, delete, start and emulate RAW signal
* SubGhz: fix triangle glitch in save raw view
* SubGhz: fix receiver config scene
* SubGhz: fix transfer after returning from save scene
* Canvas: add font rotation
* SubGhz: raw protocol encoder
* SubGhz: fix error completion of transfer raw encoder
* SubGhz: increased the speed of reading RAW data from a flash drive, displaying the name of the saved file in the Save RAW scene
* Canvas: fix font rotation
* SubGhz: fix navigation save RAW scene
* SubGhz: add decode came atomo
* Git: renormalize
* Cleanup sources and enums
* Gui: add font direction to canvas reset, canvas init sequence cleanup.
* SubGhz: reorder menu.
* Gui: correct canvas_set_font_direction signature
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Diffstat (limited to 'applications/subghz/views')
-rw-r--r-- | applications/subghz/views/subghz_frequency_analyzer.h | 7 | ||||
-rw-r--r-- | applications/subghz/views/subghz_receiver.c | 7 | ||||
-rw-r--r-- | applications/subghz/views/subghz_receiver.h | 9 | ||||
-rw-r--r-- | applications/subghz/views/subghz_save_raw.c | 313 | ||||
-rw-r--r-- | applications/subghz/views/subghz_save_raw.h | 30 | ||||
-rw-r--r-- | applications/subghz/views/subghz_transmitter.c | 6 | ||||
-rw-r--r-- | applications/subghz/views/subghz_transmitter.h | 10 |
7 files changed, 357 insertions, 25 deletions
diff --git a/applications/subghz/views/subghz_frequency_analyzer.h b/applications/subghz/views/subghz_frequency_analyzer.h index ebfcb173..78280503 100644 --- a/applications/subghz/views/subghz_frequency_analyzer.h +++ b/applications/subghz/views/subghz_frequency_analyzer.h @@ -1,14 +1,11 @@ #pragma once #include <gui/view.h> - -typedef enum { - SubghzFrequencyAnalyzerEventOnlyRx, -} SubghzFrequencyAnalyzerEvent; +#include "../helpers/subghz_custom_event.h" typedef struct SubghzFrequencyAnalyzer SubghzFrequencyAnalyzer; -typedef void (*SubghzFrequencyAnalyzerCallback)(SubghzFrequencyAnalyzerEvent event, void* context); +typedef void (*SubghzFrequencyAnalyzerCallback)(SubghzCustomEvent event, void* context); void subghz_frequency_analyzer_set_callback( SubghzFrequencyAnalyzer* subghz_frequency_analyzer, diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index 26aec5e7..f854e81d 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -181,7 +181,7 @@ bool subghz_receiver_input(InputEvent* event, void* context) { SubghzReceiver* subghz_receiver = context; if(event->key == InputKeyBack && event->type == InputTypeShort) { - subghz_receiver->callback(SubghzReceverEventBack, subghz_receiver->context); + subghz_receiver->callback(SubghzCustomEventViewReceverBack, subghz_receiver->context); } else if( event->key == InputKeyUp && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { @@ -199,12 +199,13 @@ bool subghz_receiver_input(InputEvent* event, void* context) { return true; }); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { - subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context); + subghz_receiver->callback(SubghzCustomEventViewReceverConfig, subghz_receiver->context); } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { if(model->history_item != 0) { - subghz_receiver->callback(SubghzReceverEventOK, subghz_receiver->context); + subghz_receiver->callback( + SubghzCustomEventViewReceverOK, subghz_receiver->context); } return false; }); diff --git a/applications/subghz/views/subghz_receiver.h b/applications/subghz/views/subghz_receiver.h index be9a9ef1..e26ee2c2 100644 --- a/applications/subghz/views/subghz_receiver.h +++ b/applications/subghz/views/subghz_receiver.h @@ -1,16 +1,11 @@ #pragma once #include <gui/view.h> - -typedef enum { - SubghzReceverEventOK, - SubghzReceverEventConfig, - SubghzReceverEventBack, -} SubghzReceverEvent; +#include "../helpers/subghz_custom_event.h" typedef struct SubghzReceiver SubghzReceiver; -typedef void (*SubghzReceiverCallback)(SubghzReceverEvent event, void* context); +typedef void (*SubghzReceiverCallback)(SubghzCustomEvent event, void* context); void subghz_receiver_set_callback( SubghzReceiver* subghz_receiver, diff --git a/applications/subghz/views/subghz_save_raw.c b/applications/subghz/views/subghz_save_raw.c new file mode 100644 index 00000000..b496cef7 --- /dev/null +++ b/applications/subghz/views/subghz_save_raw.c @@ -0,0 +1,313 @@ +#include "subghz_save_raw.h" +#include "../subghz_i.h" + +#include <math.h> +#include <furi.h> +#include <furi-hal.h> +#include <input/input.h> +#include <gui/elements.h> +#include <lib/subghz/protocols/subghz_protocol_princeton.h> + +#include <assets_icons.h> +#define SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE 100 + +typedef enum { + SubghzSaveRAWStatusStart, + SubghzSaveRAWStatusIDLE, + SubghzSaveRAWStatusREC, + SubghzSaveRAWStatusShowName, +} SubghzSaveRAWStatus; + +struct SubghzSaveRAW { + View* view; + osTimerId timer; + SubghzSaveRAWCallback callback; + void* context; +}; + +typedef struct { + string_t frequency_str; + string_t preset_str; + string_t sample_write; + string_t file_name; + uint8_t* rssi_history; + bool rssi_history_end; + uint8_t ind_write; + SubghzSaveRAWStatus satus; +} SubghzSaveRAWModel; + +void subghz_save_raw_set_callback( + SubghzSaveRAW* subghz_save_raw, + SubghzSaveRAWCallback callback, + void* context) { + furi_assert(subghz_save_raw); + furi_assert(callback); + subghz_save_raw->callback = callback; + subghz_save_raw->context = context; +} + +void subghz_save_raw_add_data_statusbar( + SubghzSaveRAW* instance, + const char* frequency_str, + const char* preset_str) { + furi_assert(instance); + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + string_set(model->frequency_str, frequency_str); + string_set(model->preset_str, preset_str); + return true; + }); +} + +void subghz_save_raw_set_file_name(SubghzSaveRAW* instance, const char* file_name) { + furi_assert(instance); + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + string_set(model->file_name, file_name); + return true; + }); +} + +static void subghz_save_raw_timer_callback(void* context) { + furi_assert(context); + SubghzSaveRAW* instance = context; + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + model->satus = SubghzSaveRAWStatusIDLE; + return true; + }); +} + +void subghz_save_raw_add_data_rssi(SubghzSaveRAW* instance, float rssi) { + furi_assert(instance); + uint8_t u_rssi = 0; + + if(rssi < -90) { + u_rssi = 0; + } else { + u_rssi = (uint8_t)((rssi + 90) / 2.7); + } + //if(u_rssi > 34) u_rssi = 34; + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + model->rssi_history[model->ind_write++] = u_rssi; + if(model->ind_write > SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE) { + model->rssi_history_end = true; + model->ind_write = 0; + } + return true; + }); +} + +void subghz_save_raw_update_sample_write(SubghzSaveRAW* instance, size_t sample) { + furi_assert(instance); + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + string_printf(model->sample_write, "%d spl.", sample); + return false; + }); +} + +void subghz_save_raw_draw_rssi(Canvas* canvas, SubghzSaveRAWModel* model) { + int ind = 0; + int base = 0; + if(model->rssi_history_end == false) { + for(int i = model->ind_write; i >= 0; i--) { + canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[i]); + } + if(model->ind_write > 3) { + canvas_draw_line(canvas, model->ind_write, 47, model->ind_write, 13); + canvas_draw_line(canvas, model->ind_write - 2, 12, model->ind_write + 2, 12); + canvas_draw_line(canvas, model->ind_write - 1, 13, model->ind_write + 1, 13); + } + } else { + base = SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - model->ind_write; + for(int i = SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE; i >= 0; i--) { + ind = i - base; + if(ind < 0) ind += SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE; + canvas_draw_line(canvas, i, 47, i, 47 - model->rssi_history[ind]); + } + canvas_draw_line( + canvas, SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE, 47, SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE, 13); + canvas_draw_line( + canvas, + SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - 2, + 12, + SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE + 2, + 12); + canvas_draw_line( + canvas, + SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE - 1, + 13, + SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE + 1, + 13); + } +} + +void subghz_save_raw_draw(Canvas* canvas, SubghzSaveRAWModel* model) { + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + if(model->satus != SubghzSaveRAWStatusShowName) { + canvas_draw_str(canvas, 5, 8, string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 40, 8, string_get_cstr(model->preset_str)); + canvas_draw_str_aligned( + canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); + } else { + canvas_draw_str_aligned( + canvas, 61, 1, AlignRight, AlignTop, string_get_cstr(model->file_name)); + canvas_draw_str(canvas, 65, 8, "Saved!"); + } + + canvas_draw_line(canvas, 0, 14, 115, 14); + subghz_save_raw_draw_rssi(canvas, model); + canvas_draw_line(canvas, 0, 48, 115, 48); + canvas_draw_line(canvas, 115, 14, 115, 48); + + if(model->satus == SubghzSaveRAWStatusIDLE) { + elements_button_left(canvas, "Config"); + elements_button_center(canvas, "REC"); + elements_button_right(canvas, "More"); + } else if(model->satus == SubghzSaveRAWStatusStart) { + elements_button_left(canvas, "Config"); + elements_button_center(canvas, "REC"); + } else { + elements_button_center(canvas, "Stop"); + } + + canvas_set_font_direction(canvas, 3); + canvas_draw_str(canvas, 126, 40, "RSSI"); + canvas_set_font_direction(canvas, 0); +} + +bool subghz_save_raw_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzSaveRAW* instance = context; + + if(event->key == InputKeyBack && event->type == InputTypeShort) { + instance->callback(SubghzCustomEventViewSaveRAWBack, instance->context); + } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + if(model->satus == SubghzSaveRAWStatusIDLE || + model->satus == SubghzSaveRAWStatusStart) { + instance->callback(SubghzCustomEventViewSaveRAWConfig, instance->context); + } + return true; + }); + } else if(event->key == InputKeyRight && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + if(model->satus == SubghzSaveRAWStatusIDLE) { + instance->callback(SubghzCustomEventViewSaveRAWMore, instance->context); + } + return true; + }); + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + if(model->satus == SubghzSaveRAWStatusIDLE || + model->satus == SubghzSaveRAWStatusStart) { + instance->callback(SubghzCustomEventViewSaveRAWREC, instance->context); + model->satus = SubghzSaveRAWStatusREC; + model->ind_write = 0; + model->rssi_history_end = false; + } else { + instance->callback(SubghzCustomEventViewSaveRAWIDLE, instance->context); + model->satus = SubghzSaveRAWStatusShowName; + osTimerStart(instance->timer, 1024); + } + return true; + }); + } + + if(event->key == InputKeyBack) { + return false; + } + + return true; +} + +void subghz_save_raw_enter(void* context) { + furi_assert(context); + SubghzSaveRAW* instance = context; + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + model->satus = SubghzSaveRAWStatusStart; + model->rssi_history = furi_alloc(SUBGHZ_SAVE_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); + model->rssi_history_end = false; + model->ind_write = 0; + string_set(model->sample_write, "0 spl."); + return true; + }); +} + +void subghz_save_raw_exit(void* context) { + furi_assert(context); + SubghzSaveRAW* instance = context; + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + if(model->satus != SubghzSaveRAWStatusIDLE && + model->satus != SubghzSaveRAWStatusStart) { + instance->callback(SubghzCustomEventViewSaveRAWIDLE, instance->context); + model->satus = SubghzSaveRAWStatusStart; + } + string_clean(model->frequency_str); + string_clean(model->preset_str); + string_clean(model->sample_write); + string_clean(model->file_name); + free(model->rssi_history); + return true; + }); +} + +SubghzSaveRAW* subghz_save_raw_alloc() { + SubghzSaveRAW* instance = furi_alloc(sizeof(SubghzSaveRAW)); + + // View allocation and configuration + instance->view = view_alloc(); + view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(SubghzSaveRAWModel)); + view_set_context(instance->view, instance); + view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_save_raw_draw); + view_set_input_callback(instance->view, subghz_save_raw_input); + view_set_enter_callback(instance->view, subghz_save_raw_enter); + view_set_exit_callback(instance->view, subghz_save_raw_exit); + + instance->timer = osTimerNew(subghz_save_raw_timer_callback, osTimerOnce, instance, NULL); + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + string_init(model->frequency_str); + string_init(model->preset_str); + string_init(model->sample_write); + string_init(model->file_name); + return true; + }); + + return instance; +} + +void subghz_save_raw_free(SubghzSaveRAW* instance) { + furi_assert(instance); + + with_view_model( + instance->view, (SubghzSaveRAWModel * model) { + string_clear(model->frequency_str); + string_clear(model->preset_str); + string_clear(model->sample_write); + string_clear(model->file_name); + return true; + }); + osTimerDelete(instance->timer); + view_free(instance->view); + free(instance); +} + +View* subghz_save_raw_get_view(SubghzSaveRAW* instance) { + furi_assert(instance); + return instance->view; +}
\ No newline at end of file diff --git a/applications/subghz/views/subghz_save_raw.h b/applications/subghz/views/subghz_save_raw.h new file mode 100644 index 00000000..25d86cf9 --- /dev/null +++ b/applications/subghz/views/subghz_save_raw.h @@ -0,0 +1,30 @@ +#pragma once + +#include <gui/view.h> +#include "../helpers/subghz_custom_event.h" + +typedef struct SubghzSaveRAW SubghzSaveRAW; + +typedef void (*SubghzSaveRAWCallback)(SubghzCustomEvent event, void* context); + +void subghz_save_raw_set_callback( + SubghzSaveRAW* subghz_save_raw, + SubghzSaveRAWCallback callback, + void* context); + +SubghzSaveRAW* subghz_save_raw_alloc(); + +void subghz_save_raw_free(SubghzSaveRAW* subghz_static); + +void subghz_save_raw_add_data_statusbar( + SubghzSaveRAW* instance, + const char* frequency_str, + const char* preset_str); + +void subghz_save_raw_set_file_name(SubghzSaveRAW* instance, const char* file_name); + +void subghz_save_raw_update_sample_write(SubghzSaveRAW* instance, size_t sample); + +void subghz_save_raw_add_data_rssi(SubghzSaveRAW* instance, float rssi); + +View* subghz_save_raw_get_view(SubghzSaveRAW* subghz_static); diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c index 6e29f5dd..b5adf3e9 100644 --- a/applications/subghz/views/subghz_transmitter.c +++ b/applications/subghz/views/subghz_transmitter.c @@ -111,10 +111,12 @@ bool subghz_transmitter_input(InputEvent* event, void* context) { }); if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { - subghz_transmitter->callback(SubghzTransmitterEventSendStart, subghz_transmitter->context); + subghz_transmitter->callback( + SubghzCustomEventViewTransmitterSendStart, subghz_transmitter->context); return true; } else if(can_be_sent && event->key == InputKeyOk && event->type == InputTypeRelease) { - subghz_transmitter->callback(SubghzTransmitterEventSendStop, subghz_transmitter->context); + subghz_transmitter->callback( + SubghzCustomEventViewTransmitterSendStop, subghz_transmitter->context); return true; } diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h index 8ddeaaf8..995e08f6 100644 --- a/applications/subghz/views/subghz_transmitter.h +++ b/applications/subghz/views/subghz_transmitter.h @@ -1,17 +1,11 @@ #pragma once #include <gui/view.h> - -typedef enum { - SubghzTransmitterEventSendStart, - SubghzTransmitterEventSendStop, - SubghzTransmitterEventBack, - SubghzTransmitterEventNoMan, -} SubghzTransmitterEvent; +#include "../helpers/subghz_custom_event.h" typedef struct SubghzTransmitter SubghzTransmitter; -typedef void (*SubghzTransmitterCallback)(SubghzTransmitterEvent event, void* context); +typedef void (*SubghzTransmitterCallback)(SubghzCustomEvent event, void* context); void subghz_transmitter_set_callback( SubghzTransmitter* subghz_transmitter, |