From e17336498db48de0898313aca9099985b91bd89e Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 2 Sep 2021 01:05:00 +0400 Subject: [PATCH] [FL-1756, FL-1769, FL-1776, FL-1759] Gui: input events complementary V3, refactoring. SubGhz: read/emulate fixes. Cleanup. (#684) * Gui: move rotation logic to ViewPort, replace delayed View switch in ViewDispatcher with event filtering and redirection to previous view. * SubGhz: add function description * Gui, Input: add event id to input events. * SubGhz: fix "crashing on ?" * SubGhz: add icon scanning * SubGhz: updated interface read scene, updated interface config scene * Assets: update subghz assets * SubGhz: replaced the picture in the read scene, changed the paths to additional files * SubGhz: fix deadlock in timer callback * SubGhz: fix icon read scene * SubGhz: fix icon read scene * SubGhz: fix duble text transmitter scene * SubGhz: correct spelling. Gui: bigger queue for ViewDispatcher. * SubGhz: fix creation and transmission of dynamic code without the presence of a manufactory key * SubGhz: fix keelog, setting a name in the absence of a manufactory key * SubGhz: fix load bad keelog key * Format sources * Furi: remove garbage from core. GpioTester: fix memory leak and cleanup * Accessor: remove obsolete notification code * MusicPlayer: remove input event injection * Input: rename id to sequence Co-authored-by: Aleksandr Kutuzov --- applications/accessor/accessor-app.cpp | 12 -- applications/accessor/accessor-app.h | 2 - applications/gpio-tester/gpio-tester.c | 197 +++++++++--------- applications/gui/canvas.c | 9 +- applications/gui/gui.c | 83 +++----- applications/gui/view_dispatcher.c | 80 ++++--- applications/gui/view_dispatcher_i.h | 2 +- applications/gui/view_port.c | 31 +++ applications/input/input.c | 5 + applications/input/input.h | 1 + applications/input/input_i.h | 2 + applications/music-player/music-player.c | 27 +-- .../subghz/scenes/subghz_scene_config.h | 1 + .../subghz/scenes/subghz_scene_no_man.c | 48 +++++ .../subghz/scenes/subghz_scene_receiver.c | 4 + .../subghz/scenes/subghz_scene_set_type.c | 14 +- .../subghz/scenes/subghz_scene_transmitter.c | 5 + applications/subghz/subghz.c | 4 +- applications/subghz/subghz_cli.c | 4 +- applications/subghz/subghz_history.c | 14 +- applications/subghz/subghz_history.h | 85 +++++++- applications/subghz/views/subghz_receiver.c | 123 ++++++----- applications/subghz/views/subghz_receiver.h | 3 +- .../subghz/views/subghz_transmitter.c | 29 ++- .../subghz/views/subghz_transmitter.h | 1 + assets/compiled/assets_icons.c | 32 ++- assets/compiled/assets_icons.h | 10 +- assets/icons/GubGHz/Broadcast_dolph_67-61.png | Bin 3894 -> 0 bytes assets/icons/GubGHz/Scanning_123x52.png | Bin 0 -> 1690 bytes assets/icons/GubGHz/Scanning_dolph_67-61.png | Bin 3518 -> 0 bytes assets/icons/GubGHz/Top-frame_128-13.png | Bin 3610 -> 0 bytes core/furi-hal/api-spi.h | 144 ------------- core/furi/common_defines.h | 9 + lib/subghz/protocols/subghz_protocol_came.h | 26 ++- lib/subghz/protocols/subghz_protocol_common.h | 28 +++ .../protocols/subghz_protocol_faac_slh.h | 5 + .../protocols/subghz_protocol_gate_tx.h | 18 ++ lib/subghz/protocols/subghz_protocol_ido.h | 6 + lib/subghz/protocols/subghz_protocol_keeloq.c | 31 ++- lib/subghz/protocols/subghz_protocol_keeloq.h | 33 ++- .../protocols/subghz_protocol_nero_sketch.h | 18 ++ .../protocols/subghz_protocol_nice_flo.h | 18 ++ .../protocols/subghz_protocol_nice_flor_s.h | 6 + .../protocols/subghz_protocol_princeton.h | 26 ++- .../protocols/subghz_protocol_star_line.c | 7 +- .../protocols/subghz_protocol_star_line.h | 18 ++ lib/subghz/subghz_keystore.h | 18 ++ 47 files changed, 763 insertions(+), 476 deletions(-) create mode 100644 applications/subghz/scenes/subghz_scene_no_man.c delete mode 100644 assets/icons/GubGHz/Broadcast_dolph_67-61.png create mode 100644 assets/icons/GubGHz/Scanning_123x52.png delete mode 100644 assets/icons/GubGHz/Scanning_dolph_67-61.png delete mode 100644 assets/icons/GubGHz/Top-frame_128-13.png delete mode 100644 core/furi-hal/api-spi.h diff --git a/applications/accessor/accessor-app.cpp b/applications/accessor/accessor-app.cpp index f7446b55..b462ec79 100644 --- a/applications/accessor/accessor-app.cpp +++ b/applications/accessor/accessor-app.cpp @@ -35,7 +35,6 @@ AccessorApp::AccessorApp() : onewire_master{&ibutton_gpio} { furi_hal_power_insomnia_enter(); notification = static_cast(furi_record_open("notification")); - notify_init(); furi_hal_power_enable_otg(); } @@ -104,17 +103,6 @@ AccessorApp::Scene AccessorApp::get_previous_scene() { /***************************** NOTIFY *******************************/ -void AccessorApp::notify_init() { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - GPIO_InitStruct.Pin = PB3_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; - HAL_GPIO_Init(PB3_GPIO_Port, &GPIO_InitStruct); -} - void AccessorApp::notify_green_blink() { notification_message(notification, &sequence_blink_green_10); } diff --git a/applications/accessor/accessor-app.h b/applications/accessor/accessor-app.h index 32af88ee..daa16d7f 100644 --- a/applications/accessor/accessor-app.h +++ b/applications/accessor/accessor-app.h @@ -29,9 +29,7 @@ public: bool switch_to_previous_scene(uint8_t count = 1); Scene get_previous_scene(); - void notify_init(); void notify_green_blink(); - void notify_success(); char* get_text_store(); diff --git a/applications/gpio-tester/gpio-tester.c b/applications/gpio-tester/gpio-tester.c index 4d079632..c088a195 100644 --- a/applications/gpio-tester/gpio-tester.c +++ b/applications/gpio-tester/gpio-tester.c @@ -2,143 +2,134 @@ #include #include -#include #include typedef struct { const char* name; - GpioPin pin; + const GpioPin* pin; } GpioItem; -const GpioItem GPIO_PINS[] = { - {"1.2: PA7", {GPIOA, GPIO_PIN_7}}, - {"1.3: PA6", {GPIOA, GPIO_PIN_6}}, - {"1.4: PA4", {GPIOA, GPIO_PIN_4}}, - {"1.5: PB3", {GPIOB, GPIO_PIN_3}}, - {"1.6: PB2", {GPIOB, GPIO_PIN_2}}, - {"1.7: PC3", {GPIOC, GPIO_PIN_3}}, - - {"2.7: PC1", {GPIOC, GPIO_PIN_1}}, - {"2.8: PC0", {GPIOC, GPIO_PIN_0}}, +static const GpioItem GPIO_PINS[] = { + {"1.2: PA7", &gpio_ext_pa7}, + {"1.3: PA6", &gpio_ext_pa6}, + {"1.4: PA4", &gpio_ext_pa4}, + {"1.5: PB3", &gpio_ext_pb3}, + {"1.6: PB2", &gpio_ext_pb2}, + {"1.7: PC3", &gpio_ext_pc3}, + {"2.7: PC1", &gpio_ext_pc1}, + {"2.8: PC0", &gpio_ext_pc0}, }; -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - union { - InputEvent input; - } value; - EventType type; -} AppEvent; +static const size_t GPIO_PINS_COUNT = sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); typedef struct { + osMessageQueueId_t input_queue; uint8_t gpio_index; -} State; + ViewPort* view_port; + Gui* gui; + NotificationApp* notification; +} GpioTest; -static void render_callback(Canvas* canvas, void* ctx) { - State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); +static void gpio_test_render_callback(Canvas* canvas, void* ctx) { + GpioTest* gpio_test = ctx; canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, "GPIO Control"); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name); - - release_mutex((ValueMutex*)ctx, state); + canvas_draw_str(canvas, 2, 25, GPIO_PINS[gpio_test->gpio_index].name); } -static void input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; +static void gpio_test_input_callback(InputEvent* input_event, void* ctx) { + GpioTest* gpio_test = ctx; - AppEvent event; - event.type = EventTypeKey; - event.value.input = *input_event; - osMessageQueuePut(event_queue, &event, 0, 0); + osMessageQueuePut(gpio_test->input_queue, input_event, 0, 0); +} + +static void gpio_test_configure_pins(GpioMode mode) { + for(size_t i = 0; i < GPIO_PINS_COUNT; i++) { + hal_gpio_write(GPIO_PINS[i].pin, false); + hal_gpio_init(GPIO_PINS[i].pin, mode, GpioPullNo, GpioSpeedLow); + } +} + +GpioTest* gpio_test_alloc() { + GpioTest* instance = furi_alloc(sizeof(GpioTest)); + + gpio_test_configure_pins(GpioModeOutputPushPull); + + instance->input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + furi_check(instance->input_queue); + + instance->view_port = view_port_alloc(); + view_port_draw_callback_set(instance->view_port, gpio_test_render_callback, instance); + view_port_input_callback_set(instance->view_port, gpio_test_input_callback, instance); + + instance->gui = furi_record_open("gui"); + gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); + + instance->notification = furi_record_open("notification"); + + return instance; +} + +void gpio_test_free(GpioTest* instance) { + furi_assert(instance); + + furi_record_close("notification"); + + view_port_enabled_set(instance->view_port, false); + gui_remove_view_port(instance->gui, instance->view_port); + furi_record_close("gui"); + + view_port_free(instance->view_port); + + osMessageQueueDelete(instance->input_queue); + + gpio_test_configure_pins(GpioModeAnalog); + + free(instance); } int32_t gpio_test_app(void* p) { - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL); - furi_check(event_queue); + GpioTest* gpio_test = gpio_test_alloc(); - State _state; - _state.gpio_index = 0; + InputEvent event; + while(osMessageQueueGet(gpio_test->input_queue, &event, NULL, osWaitForever) == osOK) { + if(event.type == InputTypeShort) { + if(event.key == InputKeyBack) { + notification_message(gpio_test->notification, &sequence_reset_green); + break; + } - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("[gpio-tester] cannot create mutex\r\n"); - return 255; - } - - ViewPort* view_port = view_port_alloc(); - - view_port_draw_callback_set(view_port, render_callback, &state_mutex); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open("notification"); - - // configure pin - for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { - hal_gpio_init( - (GpioPin*)&GPIO_PINS[i].pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - } - - AppEvent event; - while(1) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); - State* state = (State*)acquire_mutex_block(&state_mutex); - - if(event_status == osOK) { - if(event.type == EventTypeKey) { - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyBack) { - printf("[gpio-tester] bye!\r\n"); - notification_message(notification, &sequence_reset_green); - furi_record_close("notification"); - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - - return 0; + if(event.key == InputKeyRight) { + if(gpio_test->gpio_index < (GPIO_PINS_COUNT - 1)) { + gpio_test->gpio_index++; } + } - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyRight) { - if(state->gpio_index < (sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]) - 1)) { - state->gpio_index++; - } + if(event.key == InputKeyLeft) { + if(gpio_test->gpio_index > 0) { + gpio_test->gpio_index--; } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyLeft) { - if(state->gpio_index > 0) { - state->gpio_index--; - } - } - - if(event.value.input.key == InputKeyOk) { - if(event.value.input.type == InputTypePress) { - hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, true); - notification_message(notification, &sequence_set_green_255); - } else if(event.value.input.type == InputTypeRelease) { - hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, false); - notification_message(notification, &sequence_reset_green); - } + } + } else { + if(event.key == InputKeyOk) { + if(event.type == InputTypePress) { + hal_gpio_write(GPIO_PINS[gpio_test->gpio_index].pin, true); + notification_message(gpio_test->notification, &sequence_set_green_255); + } else if(event.type == InputTypeRelease) { + hal_gpio_write(GPIO_PINS[gpio_test->gpio_index].pin, false); + notification_message(gpio_test->notification, &sequence_reset_green); } } } - release_mutex(&state_mutex, state); - view_port_update(view_port); + view_port_update(gpio_test->view_port); } + gpio_test_free(gpio_test); + return 0; } diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 1dee2258..02341989 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -309,12 +309,15 @@ void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) { furi_assert(canvas); if(canvas->orientation != orientation) { canvas->orientation = orientation; - if(canvas->orientation == CanvasOrientationHorizontal) + if(canvas->orientation == CanvasOrientationHorizontal) { + FURI_SWAP(canvas->width, canvas->height); u8g2_SetDisplayRotation(&canvas->fb, U8G2_R0); - else if(canvas->orientation == CanvasOrientationVertical) + } else if(canvas->orientation == CanvasOrientationVertical) { + FURI_SWAP(canvas->width, canvas->height); u8g2_SetDisplayRotation(&canvas->fb, U8G2_R3); - else + } else { furi_assert(0); + } } } diff --git a/applications/gui/gui.c b/applications/gui/gui.c index 11c6b5f8..b167db70 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -1,40 +1,5 @@ #include "gui_i.h" -static void gui_rotate_buttons(InputEvent* event) { - switch(event->key) { - case InputKeyUp: - event->key = InputKeyRight; - break; - case InputKeyDown: - event->key = InputKeyLeft; - break; - case InputKeyRight: - event->key = InputKeyDown; - break; - case InputKeyLeft: - event->key = InputKeyUp; - break; - default: - break; - } -} - -static void gui_setup_fs_orientation(const ViewPort* view_port, Canvas* canvas) { - ViewPortOrientation view_port_orientation = view_port_get_orientation(view_port); - CanvasOrientation canvas_orientation = canvas_get_orientation(canvas); - if(view_port_orientation == ViewPortOrientationHorizontal) { - canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT); - if(canvas_orientation != CanvasOrientationHorizontal) { - canvas_set_orientation(canvas, CanvasOrientationHorizontal); - } - } else if(view_port_orientation == ViewPortOrientationVertical) { - canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_HEIGHT, GUI_DISPLAY_WIDTH); - if(canvas_orientation != CanvasOrientationVertical) { - canvas_set_orientation(canvas, CanvasOrientationVertical); - } - } -} - ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) { // Iterating backward ViewPortArray_it_t it; @@ -66,9 +31,10 @@ void gui_input_events_callback(const void* value, void* ctx) { // Only Fullscreen supports vertical display for now bool gui_redraw_fs(Gui* gui) { + canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal); + canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT); ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]); if(view_port) { - gui_setup_fs_orientation(view_port, gui->canvas); view_port_draw(view_port, gui->canvas); return true; } else { @@ -225,9 +191,10 @@ void gui_input(Gui* gui, InputEvent* input_event) { } else if(!(gui->ongoing_input & key_bit)) { FURI_LOG_W( "Gui", - "non-complementary input, discarding key %s type %s", + "non-complementary input, discarding key: %s type: %s, sequence: %p", input_get_key_name(input_event->key), - input_get_type_name(input_event->type)); + input_get_type_name(input_event->type), + input_event->sequence); return; } @@ -241,21 +208,27 @@ void gui_input(Gui* gui, InputEvent* input_event) { gui->ongoing_input_view_port = view_port; } - if(view_port) { - if(view_port == gui->ongoing_input_view_port) { - if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) { - gui_rotate_buttons(input_event); - } - view_port_input(view_port, input_event); - } else { - FURI_LOG_W( - "Gui", - "ViewPort change while key press %x -> %x. Discarding key: %s, type: %s", - gui->ongoing_input_view_port, - view_port, - input_get_key_name(input_event->key), - input_get_type_name(input_event->type)); - } + if(view_port && view_port == gui->ongoing_input_view_port) { + view_port_input(view_port, input_event); + } else if(gui->ongoing_input_view_port && input_event->type == InputTypeRelease) { + FURI_LOG_W( + "Gui", + "ViewPort changed while key press %p -> %p. Sending key: %s, type: %s, sequence: %p to previous view port", + gui->ongoing_input_view_port, + view_port, + input_get_key_name(input_event->key), + input_get_type_name(input_event->type), + input_event->sequence); + view_port_input(gui->ongoing_input_view_port, input_event); + } else { + FURI_LOG_W( + "Gui", + "ViewPort changed while key press %p -> %p. Discarding key: %s, type: %s, sequence: %p", + gui->ongoing_input_view_port, + view_port, + input_get_key_name(input_event->key), + input_get_type_name(input_event->type), + input_event->sequence); } gui_unlock(gui); @@ -355,6 +328,10 @@ void gui_remove_view_port(Gui* gui, ViewPort* view_port) { } } + if(gui->ongoing_input_view_port == view_port) { + gui->ongoing_input_view_port = NULL; + } + gui_unlock(gui); } diff --git a/applications/gui/view_dispatcher.c b/applications/gui/view_dispatcher.c index ca80dcf0..b89e1c9b 100644 --- a/applications/gui/view_dispatcher.c +++ b/applications/gui/view_dispatcher.c @@ -37,7 +37,7 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher) { furi_assert(view_dispatcher); furi_assert(view_dispatcher->queue == NULL); - view_dispatcher->queue = osMessageQueueNew(8, sizeof(ViewDispatcherMessage), NULL); + view_dispatcher->queue = osMessageQueueNew(16, sizeof(ViewDispatcherMessage), NULL); } void view_dispatcher_set_event_callback_context(ViewDispatcher* view_dispatcher, void* context) { @@ -149,6 +149,10 @@ void view_dispatcher_remove_view(ViewDispatcher* view_dispatcher, uint32_t view_ if(view_dispatcher->current_view == view) { view_dispatcher_set_current_view(view_dispatcher, NULL); } + // Check if view is recieving input + if(view_dispatcher->ongoing_input_view == view) { + view_dispatcher->ongoing_input_view = NULL; + } // Remove view ViewDict_erase(view_dispatcher->views, view_id); @@ -169,12 +173,7 @@ void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t vi } else { View** view_pp = ViewDict_get(view_dispatcher->views, view_id); furi_check(view_pp != NULL); - if(view_dispatcher->ongoing_input) { - view_dispatcher->delayed_next_view = *view_pp; - } else { - view_dispatcher->delayed_next_view = NULL; - view_dispatcher_set_current_view(view_dispatcher, *view_pp); - } + view_dispatcher_set_current_view(view_dispatcher, *view_pp); } } @@ -227,39 +226,52 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e } else if(!(view_dispatcher->ongoing_input & key_bit)) { FURI_LOG_W( "ViewDispatcher", - "non-complementary input, discarding key: %s, type: %s", + "non-complementary input, discarding key: %s, type: %s, sequence: %p", input_get_key_name(event->key), - input_get_type_name(event->type)); + input_get_type_name(event->type), + event->sequence); return; } - bool is_consumed = false; - if(view_dispatcher->current_view) { - is_consumed = view_input(view_dispatcher->current_view, event); - } - if(!is_consumed && event->type == InputTypeShort) { - // TODO remove view navigation handlers - uint32_t view_id = VIEW_IGNORE; - if(event->key == InputKeyBack) { - view_id = view_previous(view_dispatcher->current_view); - if((view_id == VIEW_IGNORE) && (view_dispatcher->navigation_event_callback)) { - is_consumed = - view_dispatcher->navigation_event_callback(view_dispatcher->event_context); - if(!is_consumed) { - view_dispatcher_stop(view_dispatcher); - return; - } - } - } - if(!is_consumed) { - view_dispatcher_switch_to_view(view_dispatcher, view_id); - } + // Set ongoing input view if this is event is first press event + if(!(view_dispatcher->ongoing_input & ~key_bit) && event->type == InputTypePress) { + view_dispatcher->ongoing_input_view = view_dispatcher->current_view; } - // Delayed view switch - if(view_dispatcher->delayed_next_view && !(view_dispatcher->ongoing_input)) { - view_dispatcher_set_current_view(view_dispatcher, view_dispatcher->delayed_next_view); - view_dispatcher->delayed_next_view = NULL; + // Deliver event + if(view_dispatcher->ongoing_input_view == view_dispatcher->current_view) { + bool is_consumed = false; + if(view_dispatcher->current_view) { + is_consumed = view_input(view_dispatcher->current_view, event); + } + if(!is_consumed && event->type == InputTypeShort) { + // TODO remove view navigation handlers + uint32_t view_id = VIEW_IGNORE; + if(event->key == InputKeyBack) { + view_id = view_previous(view_dispatcher->current_view); + if((view_id == VIEW_IGNORE) && (view_dispatcher->navigation_event_callback)) { + is_consumed = + view_dispatcher->navigation_event_callback(view_dispatcher->event_context); + if(!is_consumed) { + view_dispatcher_stop(view_dispatcher); + return; + } + } + } + if(!is_consumed) { + view_dispatcher_switch_to_view(view_dispatcher, view_id); + } + } + } else if(view_dispatcher->ongoing_input_view && event->type == InputTypeRelease) { + FURI_LOG_W( + "ViewDispatcher", + "View changed while key press %p -> %p. Sending key: %s, type: %s, sequence: %p to previous view port", + view_dispatcher->ongoing_input_view, + view_dispatcher->current_view, + input_get_key_name(event->key), + input_get_type_name(event->type), + event->sequence); + view_input(view_dispatcher->ongoing_input_view, event); } } diff --git a/applications/gui/view_dispatcher_i.h b/applications/gui/view_dispatcher_i.h index 9d50432c..60c9aa47 100644 --- a/applications/gui/view_dispatcher_i.h +++ b/applications/gui/view_dispatcher_i.h @@ -17,7 +17,7 @@ struct ViewDispatcher { View* current_view; - View* delayed_next_view; + View* ongoing_input_view; uint8_t ongoing_input; ViewDispatcherCustomEventCallback custom_event_callback; diff --git a/applications/gui/view_port.c b/applications/gui/view_port.c index d65b9f7a..66560bbc 100644 --- a/applications/gui/view_port.c +++ b/applications/gui/view_port.c @@ -7,6 +7,33 @@ // TODO add mutex to view_port ops +static void view_port_rotate_buttons(InputEvent* event) { + switch(event->key) { + case InputKeyUp: + event->key = InputKeyRight; + break; + case InputKeyDown: + event->key = InputKeyLeft; + break; + case InputKeyRight: + event->key = InputKeyDown; + break; + case InputKeyLeft: + event->key = InputKeyUp; + break; + default: + break; + } +} + +static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) { + if(view_port->orientation == ViewPortOrientationHorizontal) { + canvas_set_orientation(canvas, CanvasOrientationHorizontal); + } else if(view_port->orientation == ViewPortOrientationVertical) { + canvas_set_orientation(canvas, CanvasOrientationVertical); + } +} + ViewPort* view_port_alloc() { ViewPort* view_port = furi_alloc(sizeof(ViewPort)); view_port->orientation = ViewPortOrientationHorizontal; @@ -84,6 +111,7 @@ void view_port_draw(ViewPort* view_port, Canvas* canvas) { furi_check(view_port->gui); if(view_port->draw_callback) { + view_port_setup_canvas_orientation(view_port, canvas); view_port->draw_callback(canvas, view_port->draw_callback_context); } } @@ -94,6 +122,9 @@ void view_port_input(ViewPort* view_port, InputEvent* event) { furi_check(view_port->gui); if(view_port->input_callback) { + if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) { + view_port_rotate_buttons(event); + } view_port->input_callback(event, view_port->input_callback_context); } } diff --git a/applications/input/input.c b/applications/input/input.c index 4dd4df43..62be3dba 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -23,6 +23,7 @@ inline static void input_timer_stop(osTimerId_t timer_id) { void input_press_timer_callback(void* arg) { InputPinState* input_pin = arg; InputEvent event; + event.sequence = input_pin->counter; event.key = input_pin->pin->key; input_pin->press_counter++; if(input_pin->press_counter == INPUT_LONG_PRESS_COUNTS) { @@ -158,8 +159,12 @@ int32_t input_srv() { // Short / Long / Repeat timer routine if(state) { + input->counter++; + input->pin_states[i].counter = input->counter; + event.sequence = input->pin_states[i].counter; input_timer_start(input->pin_states[i].press_timer, INPUT_PRESS_TICKS); } else { + event.sequence = input->pin_states[i].counter; input_timer_stop(input->pin_states[i].press_timer); if(input->pin_states[i].press_counter < INPUT_LONG_PRESS_COUNTS) { event.type = InputTypeShort; diff --git a/applications/input/input.h b/applications/input/input.h index 228eaaf5..fd6da95d 100644 --- a/applications/input/input.h +++ b/applications/input/input.h @@ -15,6 +15,7 @@ typedef enum { /* Input Event, dispatches with PubSub */ typedef struct { + uint32_t sequence; InputKey key; InputType type; } InputEvent; diff --git a/applications/input/input_i.h b/applications/input/input_i.h index a0f6cfc3..d0cdfa76 100644 --- a/applications/input/input_i.h +++ b/applications/input/input_i.h @@ -24,6 +24,7 @@ typedef struct { volatile uint8_t debounce; volatile osTimerId_t press_timer; volatile uint8_t press_counter; + volatile uint32_t counter; } InputPinState; /* Input state */ @@ -32,6 +33,7 @@ typedef struct { PubSub event_pubsub; InputPinState* pin_states; Cli* cli; + volatile uint32_t counter; } Input; /* Input press timer callback */ diff --git a/applications/music-player/music-player.c b/applications/music-player/music-player.c index 9fa7708d..99081804 100644 --- a/applications/music-player/music-player.c +++ b/applications/music-player/music-player.c @@ -383,11 +383,6 @@ int32_t music_player_app(void* p) { Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - // open input record - PubSub* input_events_record = furi_record_open("input_events"); - // prepare "do nothing" event - InputEvent input_event = {InputKeyRight, true}; - // start player thread // TODO change to fuirac_start osThreadAttr_t player_attr = {.name = "music_player_thread", .stack_size = 512}; @@ -410,14 +405,8 @@ int32_t music_player_app(void* p) { // press events if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) { - osThreadTerminate(player); - hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - osMessageQueueDelete(event_queue); - - return 0; + release_mutex(&state_mutex, state); + break; } if(event.value.input.type == InputTypePress && @@ -442,9 +431,6 @@ int32_t music_player_app(void* p) { } } else if(event.type == EventTypeNote) { - // send "do nothing" event to prevent display backlight off - notify_pubsub(input_events_record, &input_event); - state->note_record = event.value.note_record; for(size_t i = note_stack_size - 1; i > 0; i--) { @@ -460,5 +446,14 @@ int32_t music_player_app(void* p) { release_mutex(&state_mutex, state); } + osThreadTerminate(player); + hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close("gui"); + view_port_free(view_port); + osMessageQueueDelete(event_queue); + delete_mutex(&state_mutex); + return 0; } diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h index f11c95c3..10ecd1c6 100644 --- a/applications/subghz/scenes/subghz_scene_config.h +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -4,6 +4,7 @@ ADD_SCENE(subghz, save_name, SaveName) ADD_SCENE(subghz, save_success, SaveSuccess) ADD_SCENE(subghz, saved, Saved) ADD_SCENE(subghz, transmitter, Transmitter) +ADD_SCENE(subghz, no_man, NoMan) ADD_SCENE(subghz, test, Test) ADD_SCENE(subghz, test_static, TestStatic) ADD_SCENE(subghz, test_carrier, TestCarrier) diff --git a/applications/subghz/scenes/subghz_scene_no_man.c b/applications/subghz/scenes/subghz_scene_no_man.c new file mode 100644 index 00000000..d5f2e0de --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_no_man.c @@ -0,0 +1,48 @@ +#include "../subghz_i.h" + +#define SCENE_NO_MAN_CUSTOM_EVENT (11UL) + +void subghz_scene_no_man_popup_callback(void* context) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, SCENE_NO_MAN_CUSTOM_EVENT); +} + +const void subghz_scene_no_man_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + Popup* popup = subghz->popup; + popup_set_icon(popup, 32, 12, &I_DolphinFirstStart7_61x51); + popup_set_header(popup, "No manufactory key", 13, 8, AlignLeft, AlignBottom); + popup_set_timeout(popup, 1500); + popup_set_context(popup, subghz); + popup_set_callback(popup, subghz_scene_no_man_popup_callback); + popup_enable_timeout(popup); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewPopup); +} + +const bool subghz_scene_no_man_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SCENE_NO_MAN_CUSTOM_EVENT) { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + return true; + } + } + return false; +} + +const void subghz_scene_no_man_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + Popup* popup = subghz->popup; + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + popup_set_callback(popup, NULL); + popup_set_context(popup, NULL); + popup_set_timeout(popup, 0); + popup_disable_timeout(popup); +} diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index f0607f17..3c9ba375 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -57,6 +57,10 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event subghz->state_notifications = NOTIFICATION_IDLE_STATE; return true; break; + case SubghzReceverEventSendHistoryFull: + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + return true; + break; default: break; } diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index 8948f06e..d0981792 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -146,11 +146,15 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event subghz->protocol_result->serial = key & 0x0FFFFFFF; subghz->protocol_result->btn = 0x2; //btn 0x1, 0x2, 0x4, 0x8 subghz->protocol_result->cnt = 0x0003; - subghz_protocol_keeloq_set_manufacture_name(subghz->protocol_result, "DoorHan"); - subghz->protocol_result->code_last_found = - subghz_protocol_keeloq_gen_key(subghz->protocol_result); - - generated_protocol = true; + if(subghz_protocol_keeloq_set_manufacture_name( + subghz->protocol_result, "DoorHan")) { + subghz->protocol_result->code_last_found = + subghz_protocol_keeloq_gen_key(subghz->protocol_result); + generated_protocol = true; + } else { + generated_protocol = false; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNoMan); + } } break; diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index 3ce3ad2d..c363fff6 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -38,6 +38,11 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); return true; + } else if(event.event == SubghzTransmitterEventNoMan) { + subghz->state_notifications = NOTIFICATION_IDLE_STATE; + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneNoMan); + return true; } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->state_notifications == NOTIFICATION_TX_STATE) { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index ab99bff2..865ec8df 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -129,8 +129,8 @@ SubGhz* subghz_alloc() { subghz->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); subghz_worker_set_context(subghz->worker, subghz->protocol); - subghz_protocol_load_keeloq_file(subghz->protocol, "/ext/assets/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(subghz->protocol, "/ext/assets/subghz/nice_floor_s_rx"); + subghz_protocol_load_keeloq_file(subghz->protocol, "/ext/subghz/keeloq_mfcodes"); + subghz_protocol_load_nice_flor_s_file(subghz->protocol, "/ext/subghz/nice_floor_s_rx"); //subghz_protocol_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 3031fec1..e5da483e 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -206,8 +206,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { furi_check(instance->stream); SubGhzProtocol* protocol = subghz_protocol_alloc(); - subghz_protocol_load_keeloq_file(protocol, "/ext/assets/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(protocol, "/ext/assets/subghz/nice_floor_s_rx"); + subghz_protocol_load_keeloq_file(protocol, "/ext/subghz/keeloq_mfcodes"); + subghz_protocol_load_nice_flor_s_file(protocol, "/ext/subghz/nice_floor_s_rx"); subghz_protocol_enable_dump_text(protocol, subghz_cli_command_rx_text_callback, instance); // Configure radio diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index d5c4c894..16fac74b 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -88,9 +88,15 @@ SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, u instance->data.param1 = instance->history[idx].te; return &instance->data; } -void subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output) { +bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output) { furi_assert(instance); - string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); + if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { + if(output != NULL) string_printf(output, "Memory is FULL"); + return true; + } + if(output != NULL) + string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); + return false; } void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx) { if(instance->history[idx].code_count_bit < 33) { @@ -144,10 +150,10 @@ void subghz_history_add_to_history(SubGhzHistory* instance, void* context) { 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); + subghz_protocol_keeloq_find_and_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); + subghz_protocol_star_line_find_and_get_manufacture_name(protocol); } else if(strcmp(protocol->name, "Princeton") == 0) { instance->history[instance->last_index_write].te = subghz_protocol_princeton_get_te(protocol); diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h index 71e35cf9..a1f7ee7f 100644 --- a/applications/subghz/subghz_history.h +++ b/applications/subghz/subghz_history.h @@ -4,20 +4,103 @@ typedef struct SubGhzHistory SubGhzHistory; +/** Allocate SubGhzHistory + * + * @return SubGhzHistory* + */ SubGhzHistory* subghz_history_alloc(void); + +/** Free SubGhzHistory + * + * @param instance - SubGhzHistory instance + */ void subghz_history_free(SubGhzHistory* instance); + +/** Clear history + * + * @param instance - SubGhzHistory instance + */ void subghz_history_clean(SubGhzHistory* instance); + +/** Set frequency and preset to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @param frequency - frequency Hz + * @param preset - FuriHalSubGhzPreset preset + */ void subghz_history_set_frequency_preset( SubGhzHistory* instance, uint16_t idx, uint32_t frequency, FuriHalSubGhzPreset preset); + +/** Get frequency to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @return frequency - frequency Hz + */ uint32_t subghz_history_get_frequency(SubGhzHistory* instance, uint16_t idx); + +/** Get preset to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @return preset - FuriHalSubGhzPreset preset + */ FuriHalSubGhzPreset subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx); + +/** Get history index write + * + * @param instance - SubGhzHistory instance + * @return idx - current record index + */ uint16_t subghz_history_get_item(SubGhzHistory* instance); + +/** Get type protocol to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @return type - type protocol + */ uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx); + +/** Get name protocol to history[idx] + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @return name - const char* name protocol + */ const char* subghz_history_get_name(SubGhzHistory* instance, uint16_t idx); + +/** Get string item menu to history[idx] + * + * @param instance - SubGhzHistory instance + * @param output - string_t output + * @param idx - record index + */ void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx); -void subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output); + +/** Get string the remaining number of records to history + * + * @param instance - SubGhzHistory instance + * @param output - string_t output + * @return bool - is FUUL + */ +bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output); + +/** Add protocol to history + * + * @param instance - SubGhzHistory instance + * @param context - SubGhzProtocolCommon context + */ void subghz_history_add_to_history(SubGhzHistory* instance, void* context); + +/** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data + * + * @param instance - SubGhzHistory instance + * @param idx - record index + * @return SubGhzProtocolCommonLoad* + */ SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx); diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index d08b1d0a..df70786b 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -39,9 +39,9 @@ typedef enum { } SubGhzHopperState; static const Icon* ReceiverItemIcons[] = { - [TYPE_PROTOCOL_UNKNOWN] = &I_quest_7x8, - [TYPE_PROTOCOL_STATIC] = &I_unlock_7x8, - [TYPE_PROTOCOL_DYNAMIC] = &I_lock_7x8, + [TYPE_PROTOCOL_UNKNOWN] = &I_Quest_7x8, + [TYPE_PROTOCOL_STATIC] = &I_Unlock_7x8, + [TYPE_PROTOCOL_DYNAMIC] = &I_Lock_7x8, }; struct SubghzReceiver { @@ -53,6 +53,7 @@ struct SubghzReceiver { osTimerId timer; SubGhzHopperState hopper_state; uint8_t hopper_timeout; + uint32_t event_key_sequence; }; typedef struct { @@ -172,44 +173,40 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { string_clean(str_buff); } if(scrollbar) { - elements_scrollbar_pos(canvas, 126, 0, 49, model->idx, model->history_item); + elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); } canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Conf"); - if((model->real_frequency / 1000 % 10) > 4) { - frequency = model->real_frequency + 10000; + elements_button_left(canvas, "Config"); + canvas_draw_line(canvas, 46, 51, 125, 51); + if(subghz_history_get_text_space_left(model->history, str_buff)) { + canvas_draw_str(canvas, 54, 62, string_get_cstr(str_buff)); } else { - frequency = model->real_frequency; + if((model->real_frequency / 1000 % 10) > 4) { + frequency = model->real_frequency + 10000; + } else { + frequency = model->real_frequency; + } + snprintf( + buffer, + sizeof(buffer), + "%03ld.%02ld", + frequency / 1000000 % 1000, + frequency / 10000 % 100); + canvas_draw_str(canvas, 44, 62, buffer); + canvas_draw_str(canvas, 79, 62, "AM"); + canvas_draw_str(canvas, 96, 62, string_get_cstr(str_buff)); } - snprintf( - buffer, - sizeof(buffer), - "%03ld.%02ld", - frequency / 1000000 % 1000, - frequency / 10000 % 100); - canvas_draw_str(canvas, 40, 62, buffer); - canvas_draw_str(canvas, 75, 62, "AM"); - subghz_history_get_text_space_left(model->history, str_buff); - canvas_draw_str(canvas, 94, 62, string_get_cstr(str_buff)); - canvas_draw_line(canvas, 38, 51, 125, 51); 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_draw_icon(canvas, 0, 0, &I_Scanning_123x52); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 63, 40, "Scanning..."); + canvas_draw_str(canvas, 63, 46, "Scanning..."); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Conf"); - canvas_invert_color(canvas); - canvas_draw_box(canvas, 38, 52, 10, 10); - canvas_invert_color(canvas); + elements_button_left(canvas, "Config"); if((model->real_frequency / 1000 % 10) > 4) { frequency = model->real_frequency + 10000; } else { @@ -221,11 +218,11 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { "%03ld.%02ld", frequency / 1000000 % 1000, frequency / 10000 % 100); - canvas_draw_str(canvas, 40, 62, buffer); - canvas_draw_str(canvas, 75, 62, "AM"); + canvas_draw_str(canvas, 44, 62, buffer); + canvas_draw_str(canvas, 79, 62, "AM"); subghz_history_get_text_space_left(model->history, str_buff); - canvas_draw_str(canvas, 94, 62, string_get_cstr(str_buff)); - canvas_draw_line(canvas, 48, 51, 125, 51); + canvas_draw_str(canvas, 96, 62, string_get_cstr(str_buff)); + canvas_draw_line(canvas, 46, 51, 125, 51); break; case ReceiverSceneConfig: @@ -237,9 +234,12 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { model->real_frequency / 1000000 % 1000, model->real_frequency / 1000 % 1000); canvas_draw_str(canvas, 0, 8, buffer); + canvas_draw_str(canvas, 0, 18, "Frequency Hopping: "); } else { - canvas_draw_str(canvas, 0, 8, "Frequency: "); + canvas_draw_str(canvas, 0, 8, "Frequency: < --- >"); + canvas_draw_str(canvas, 0, 18, "Frequency Hopping: "); } + canvas_draw_str(canvas, 0, 28, "Modulation: "); elements_button_center(canvas, "Save"); break; @@ -269,6 +269,13 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { string_clear(str_buff); } +void subghz_receiver_history_full(void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + subghz_receiver->callback(SubghzReceverEventSendHistoryFull, subghz_receiver->context); + subghz_receiver->hopper_state = SubGhzHopperStateOFF; +} + bool subghz_receiver_input(InputEvent* event, void* context) { furi_assert(context); @@ -280,13 +287,11 @@ bool subghz_receiver_input(InputEvent* event, void* context) { return false; }); - if(scene != ReceiverSceneInfo && event->type != InputTypeShort) return false; - bool can_be_saved = false; switch(scene) { case ReceiverSceneMain: - if(event->key == InputKeyBack) { + if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { model->idx = 0; @@ -296,19 +301,23 @@ bool subghz_receiver_input(InputEvent* event, void* context) { return true; }); return false; - } else if(event->key == InputKeyUp) { + } else if( + event->key == InputKeyUp && + (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { if(model->idx != 0) model->idx--; return true; }); - } else if(event->key == InputKeyDown) { + } else if( + event->key == InputKeyDown && + (event->type == InputTypeShort || event->type == InputTypeRepeat)) { 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) { + } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { subghz_receiver->hopper_state = SubGhzHopperStatePause; with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { @@ -317,7 +326,8 @@ bool subghz_receiver_input(InputEvent* event, void* context) { return true; }); subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context); - } else if(event->key == InputKeyOk) { + } else if(event->key == InputKeyOk && event->type == InputTypeShort) { + subghz_receiver->event_key_sequence = event->sequence; with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { string_clean(model->text); @@ -358,18 +368,23 @@ bool subghz_receiver_input(InputEvent* event, void* 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) { + } else if( + can_be_saved && event->key == InputKeyOk && event->type == InputTypePress && + subghz_receiver->event_key_sequence != event->sequence) { subghz_receiver->hopper_state = SubGhzHopperStatePause; 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) { + } else if( + can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease && + subghz_receiver->event_key_sequence != event->sequence) { subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context); return true; } break; case ReceiverSceneConfig: + if(event->type != InputTypeShort) return false; if(event->key == InputKeyBack) { with_view_model( subghz_receiver->view, (SubghzReceiverModel * model) { @@ -396,7 +411,6 @@ bool subghz_receiver_input(InputEvent* event, void* context) { osTimerStart(subghz_receiver->timer, 1024 / 10); subghz_receiver->hopper_state = SubGhzHopperStateRunnig; } - if(subghz_history_get_item(model->history) == 0) { model->scene = ReceiverSceneStart; } else { @@ -426,6 +440,7 @@ bool subghz_receiver_input(InputEvent* event, void* context) { break; case ReceiverSceneStart: + if(event->type != InputTypeShort) return false; if(event->key == InputKeyBack) { return false; } else if(event->key == InputKeyLeft) { @@ -445,6 +460,16 @@ bool subghz_receiver_input(InputEvent* event, void* context) { } subghz_receiver_update_offset(subghz_receiver); + if(scene != ReceiverSceneInfo) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + if(subghz_history_get_text_space_left(model->history, NULL)) { + subghz_receiver_history_full(subghz_receiver); + } + return false; + }); + } + return true; } @@ -476,6 +501,9 @@ void subghz_receiver_protocol_callback(SubGhzProtocolCommon* parser, void* conte model->history_item = subghz_history_get_item(model->history); model->scene = ReceiverSceneMain; + if(subghz_history_get_text_space_left(model->history, NULL)) { + subghz_receiver_history_full(subghz_receiver); + } return true; }); subghz_protocol_reset(subghz_receiver->protocol); @@ -528,10 +556,11 @@ static void subghz_receiver_timer_callback(void* context) { } // Restart radio - subghz_rx_end(subghz_receiver->worker); + furi_hal_subghz_idle(); subghz_protocol_reset(subghz_receiver->protocol); - model->real_frequency = - subghz_rx(subghz_receiver->worker, subghz_frequencies_hopper[model->frequency]); + model->real_frequency = furi_hal_subghz_set_frequency_and_path( + subghz_frequencies_hopper[model->frequency]); + furi_hal_subghz_rx(); return true; }); diff --git a/applications/subghz/views/subghz_receiver.h b/applications/subghz/views/subghz_receiver.h index 400b5c13..513f438c 100644 --- a/applications/subghz/views/subghz_receiver.h +++ b/applications/subghz/views/subghz_receiver.h @@ -14,7 +14,8 @@ typedef enum { SubghzReceverEventBack, SubghzReceverEventMore, SubghzReceverEventSendStart, - SubghzReceverEventSendStop + SubghzReceverEventSendStop, + SubghzReceverEventSendHistoryFull, } SubghzReceverEvent; typedef struct SubghzReceiver SubghzReceiver; diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c index 814eae66..1dd4e7d9 100644 --- a/applications/subghz/views/subghz_transmitter.c +++ b/applications/subghz/views/subghz_transmitter.c @@ -7,6 +7,7 @@ #include #include #include +#include struct SubghzTransmitter { View* view; @@ -100,6 +101,10 @@ void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) { canvas_draw_str(canvas, 90, 8, buffer); if(model->protocol && model->protocol->get_upload_protocol) { + if((!strcmp(model->protocol->name, "KeeLoq")) && + (!strcmp(subghz_protocol_keeloq_get_manufacture_name(model->protocol), "Unknown"))) { + return; + } subghz_transmitter_button_right(canvas, "Send"); } } @@ -107,22 +112,33 @@ void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) { bool subghz_transmitter_input(InputEvent* event, void* context) { furi_assert(context); SubghzTransmitter* subghz_transmitter = context; - bool can_be_send = false; + bool can_be_sent = false; + + if(event->key == InputKeyBack) { + return false; + } + with_view_model( subghz_transmitter->view, (SubghzTransmitterModel * model) { - can_be_send = (model->protocol && model->protocol->get_upload_protocol); + if(model->protocol && model->protocol->get_upload_protocol) { + if((!strcmp(model->protocol->name, "KeeLoq")) && + (!strcmp( + subghz_protocol_keeloq_get_manufacture_name(model->protocol), "Unknown"))) { + return false; + } + can_be_sent = true; + } + //can_be_sent = (model->protocol && model->protocol->get_upload_protocol); string_clean(model->text); model->protocol->to_string(model->protocol, model->text); return true; }); //if(event->type != InputTypeShort) return false; - if(event->key == InputKeyBack) { - return false; - } else if(can_be_send && event->key == InputKeyOk && event->type == InputTypePress) { + if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { subghz_transmitter->callback(SubghzTransmitterEventSendStart, subghz_transmitter->context); return true; - } else if(can_be_send && event->key == InputKeyOk && event->type == InputTypeRelease) { + } else if(can_be_sent && event->key == InputKeyOk && event->type == InputTypeRelease) { subghz_transmitter->callback(SubghzTransmitterEventSendStop, subghz_transmitter->context); return true; } @@ -147,6 +163,7 @@ void subghz_transmitter_enter(void* context) { SubghzTransmitter* subghz_transmitter = context; with_view_model( subghz_transmitter->view, (SubghzTransmitterModel * model) { + string_clean(model->text); model->protocol->to_string(model->protocol, model->text); return true; }); diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h index 6f289e4d..c4dd5982 100644 --- a/applications/subghz/views/subghz_transmitter.h +++ b/applications/subghz/views/subghz_transmitter.h @@ -7,6 +7,7 @@ typedef enum { SubghzTransmitterEventSendStart, SubghzTransmitterEventSendStop, SubghzTransmitterEventBack, + SubghzTransmitterEventNoMan, } SubghzTransmitterEvent; typedef struct SubghzTransmitter SubghzTransmitter; diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index af195b64..f95f04c1 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -98,23 +98,17 @@ const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0xF8,0x03,0x01,0x00,0x00,0x08,0x00,0x00,0x04,0xBC,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0xC0,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x02,0x00,0x38,0x40,0x00,0x00,0x02,0x00,0x04,0x00,0x3E,0x40,0x00,0x00,0xF4,0x03,0x08,0x80,0x07,0x80,0x00,0x00,0x5C,0x0D,0x10,0xE0,0x01,0x80,0x00,0x00,0xA8,0x3A,0x20,0xE0,0x00,0x00,0x01,0x00,0x58,0x55,0x00,0xC0,0x01,0x00,0x01,0x00,0xB0,0xAA,0x00,0x80,0x07,0x00,0x01,0x00,0x60,0x55,0x01,0x00,0x1E,0x00,0x01,0x0E,0xC0,0xAA,0x02,0xE0,0x5C,0x00,0x01,0x11,0x80,0x55,0x05,0x00,0xA9,0x00,0x01,0x21,0x00,0xAB,0x0A,0x00,0x56,0x07,0x01,0x41,0x00,0x56,0x15,0x00,0xEC,0x08,0x01,0x81,0x00,0xBF,0x2A,0x00,0x34,0x08,0x01,0x01,0xF1,0xC0,0x57,0x00,0x0C,0x08,0x01,0x02,0x0A,0x00,0xBE,0x00,0x04,0x08,0x01,0x02,0x06,0x00,0x78,0x83,0x02,0x04,0x01,0x02,0x0C,0x00,0xF0,0x7F,0x01,0x04,0x01,0x02,0xF4,0x01,0xFE,0x81,0x00,0x04,0x01,0x04,0x08,0xFF,0x6B,0x40,0x00,0x02,0x01,0x04,0x88,0x55,0x1D,0x40,0x00,0x02,0x01,0x04,0x50,0xAA,0x06,0x20,0x00,0x02,0x01,0x04,0x30,0xD4,0x01,0x20,0x00,0x01,0x01,0x04,0x10,0x68,0x00,0x10,0x00,0x01,0x01,0x04,0x18,0x18,0x00,0x10,0x00,0x01,0x01,0x08,0x18,0x06,0x80,0x10,0x00,0x01,0x01,0x08,0xE8,0x01,0x60,0x08,0x80,0x00,0x01,0x08,0x08,0x00,0x18,0x08,0x80,0x00,0x00,0x08,0x10,0x00,0x06,0x08,0x80,0x00,0x00,0x08,0x60,0xE0,0x01,0x08,0x80,0x00,0x00,0x08,0x80,0x1F,0x00,0x08,0x80,0x00,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x06,0x00,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; -const uint8_t _I_quest_7x8_0[] = {0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; -const uint8_t *_I_quest_7x8[] = {_I_quest_7x8_0}; +const uint8_t _I_Scanning_123x52_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x07,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x03,0x18,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x56,0x05,0x60,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x81,0x0A,0x80,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x15,0x00,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x38,0x00,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x20,0x00,0x74,0x00,0x04,0x00,0x00,0x40,0x82,0x01,0x00,0x00,0x00,0x41,0x00,0x00,0x20,0x00,0x68,0x00,0x04,0x00,0x00,0x20,0x82,0x02,0x06,0x00,0x00,0x21,0x00,0x00,0x10,0x00,0xD0,0xE0,0x0F,0x00,0x00,0x20,0x82,0x02,0x0A,0x0C,0x80,0x20,0x08,0x00,0x10,0x00,0xA0,0x1C,0x10,0x00,0x00,0x20,0x82,0x02,0x0A,0x14,0x80,0x10,0x04,0x00,0x08,0xE0,0xD3,0x03,0x10,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0x90,0xA7,0x40,0x24,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0xC8,0x7F,0x84,0x28,0x00,0x00,0x10,0x84,0x02,0x0A,0xFF,0x80,0x10,0x02,0x00,0x88,0x67,0x3E,0x88,0x28,0x00,0x00,0x10,0x84,0xFA,0xFF,0xFF,0x80,0x10,0x02,0x00,0x44,0x64,0x2E,0x88,0x28,0x00,0x00,0x10,0xFC,0xAF,0xFF,0x15,0x80,0x10,0x04,0x00,0x44,0xE4,0x2F,0x88,0x2A,0x00,0x00,0x18,0xD4,0xDF,0x1F,0x14,0x80,0x20,0x08,0x00,0x44,0xE4,0x2F,0x50,0xFF,0x00,0xFE,0x1F,0xEC,0x3F,0x0A,0x14,0x00,0x21,0x00,0x00,0x44,0xC4,0x2F,0xEA,0x00,0x01,0x01,0x1A,0xFC,0x02,0x0A,0x14,0x00,0x41,0x00,0x00,0x84,0x88,0x2F,0x1D,0x00,0x82,0x7D,0x1E,0x84,0x02,0x0A,0x18,0x00,0x82,0x00,0x00,0x86,0x1F,0xC6,0x06,0x00,0x84,0x7D,0x16,0x84,0x02,0x0A,0x00,0x00,0x02,0x00,0x00,0x46,0xF5,0xC3,0x01,0x00,0x44,0x01,0x22,0x84,0x02,0x0C,0x00,0x00,0x04,0x00,0x00,0x87,0x0A,0x7C,0x00,0x00,0x44,0x03,0x22,0x88,0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x45,0x05,0x08,0x00,0x7E,0xA4,0x03,0x42,0x88,0x02,0x00,0x00,0x00,0x10,0x00,0x00,0x86,0x06,0x00,0xC0,0x81,0xA5,0x07,0x42,0x08,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x30,0x00,0xD2,0xFF,0x81,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0xD2,0x1F,0x80,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x80,0x00,0x03,0x00,0xD1,0x1F,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xE1,0x00,0x80,0xE9,0x0F,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x1E,0x00,0xC0,0xE8,0x0F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x70,0xEE,0x0F,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x3C,0xF9,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xAA,0x9F,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x55,0xFD,0x5F,0xF0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0xEA,0xFF,0x3F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0xD5,0xFF,0x1F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0xAA,0xFF,0x0F,0xE0,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x55,0x55,0x03,0xF0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xAA,0xAA,0x00,0xB0,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x54,0x75,0x00,0x58,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xA8,0x0F,0x00,0xA8,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x7C,0x00,0x00,0x5C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xAE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0xD7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x80,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Scanning_123x52[] = {_I_Scanning_123x52_0}; -const uint8_t _I_unlock_7x8_0[] = {0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; -const uint8_t *_I_unlock_7x8[] = {_I_unlock_7x8_0}; +const uint8_t _I_Quest_7x8_0[] = {0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; +const uint8_t *_I_Quest_7x8[] = {_I_Quest_7x8_0}; -const uint8_t _I_Scanning_dolph_67_61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x20,0x00,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x10,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x10,0x00,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x00,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0x40,0x00,0x04,0x04,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x04,0x04,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x04,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x20,0x00,0x00,0x00,0x3C,0x04,0x02,0x81,0x00,0x10,0x00,0x00,0x00,0x42,0x04,0x02,0x41,0x00,0x10,0x00,0x00,0x00,0x81,0x08,0x02,0x41,0x00,0x08,0x06,0x00,0x80,0x18,0x09,0x02,0x41,0x00,0x08,0x09,0x08,0x80,0x24,0x09,0x02,0x41,0x00,0x84,0x10,0x08,0x80,0x24,0x11,0x02,0x41,0x00,0xC4,0x10,0x10,0x80,0x24,0x11,0x02,0x81,0x00,0x44,0x10,0x10,0x80,0x24,0x11,0x02,0x02,0x00,0x46,0x20,0x20,0x80,0x24,0x11,0x04,0x02,0x00,0x2A,0x20,0x20,0x80,0x24,0x11,0x04,0x04,0x00,0x36,0x20,0x40,0x80,0x18,0x11,0x04,0x04,0x00,0x1B,0xE0,0x80,0x00,0x81,0x10,0x08,0x08,0x00,0x0D,0xE0,0x00,0x01,0x42,0x10,0x08,0x00,0x00,0x07,0xE0,0x01,0x00,0x3C,0x18,0x10,0x00,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x10,0x00,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x20,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,}; -const uint8_t *_I_Scanning_dolph_67_61[] = {_I_Scanning_dolph_67_61_0}; +const uint8_t _I_Unlock_7x8_0[] = {0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; +const uint8_t *_I_Unlock_7x8[] = {_I_Unlock_7x8_0}; -const uint8_t _I_Broadcast_dolph_67_61_0[] = {0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x40,0x00,0x00,0xC0,0x01,0xE0,0x01,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x00,0x80,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x20,0x00,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x40,0x00,0x00,0x02,0x02,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x02,0x02,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x02,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x20,0x00,0x00,0x00,0x3C,0x04,0x10,0x08,0x04,0x10,0x00,0x00,0x00,0x42,0x04,0x20,0x08,0x04,0x10,0x00,0x00,0x00,0x81,0x08,0x20,0x08,0x04,0x08,0x06,0x00,0x80,0x18,0x09,0x20,0x08,0x04,0x08,0x09,0x08,0x80,0x24,0x09,0x20,0x08,0x04,0x84,0x10,0x08,0x80,0x24,0x11,0x20,0x08,0x04,0xC4,0x10,0x10,0x80,0x24,0x11,0x10,0x08,0x04,0x44,0x10,0x10,0x80,0x24,0x11,0x00,0x04,0x04,0x46,0x20,0x20,0x80,0x24,0x11,0x00,0x04,0x02,0x2A,0x20,0x20,0x80,0x24,0x11,0x00,0x02,0x02,0x36,0x20,0x40,0x80,0x18,0x11,0x00,0x02,0x02,0x1B,0xE0,0x80,0x00,0x81,0x10,0x00,0x01,0x01,0x0D,0xE0,0x00,0x01,0x42,0x10,0x00,0x00,0x01,0x07,0xE0,0x01,0x00,0x3C,0x18,0x00,0x80,0x00,0x03,0xF0,0x01,0x00,0x00,0x14,0x00,0x80,0x00,0x01,0xF0,0x03,0x00,0x00,0x0A,0x00,0x40,0x00,0x00,0xD0,0xFF,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0xD0,0xFF,0x01,0x00,0x0C,0x00,0x00,0x00,0x00,0x18,0xFF,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x08,0x3C,0x00,0x1F,0x0E,0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x80,0x06,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x00,0x02,0x00,0x07,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x05,0x18,0x00,0x00,0x10,0x00,0x00,0x00,0xC0,0x02,0x20,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x05,0xC0,0x00,0x00,0x20,0x00,0x00,0x00,0xA0,0x02,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x50,0x01,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0xB0,0x00,0x14,0x08,0x00,0x40,0x00,0x00,0x00,0x58,0x00,0x6A,0x30,0x00,0x40,0x00,0x00,0x00,0xAC,0x00,0xD4,0x41,0x00,0x40,0x00,0x00,0x00,0x54,0x00,0xA8,0x83,0x01,0x40,0x00,0x00,0x00,0x2A,0x00,0x50,0x0F,0x02,0x40,0x00,0x00,0x00,0x15,0x00,0xA0,0x1E,0xFC,0x5F,0x00,0x00,0x00,0x0B,0x00,0x40,0x7D,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0xA0,0xFA,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,}; -const uint8_t *_I_Broadcast_dolph_67_61[] = {_I_Broadcast_dolph_67_61_0}; - -const uint8_t _I_lock_7x8_0[] = {0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; -const uint8_t *_I_lock_7x8[] = {_I_lock_7x8_0}; - -const uint8_t _I_Top_frame_128_13_0[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,}; -const uint8_t *_I_Top_frame_128_13[] = {_I_Top_frame_128_13_0}; +const uint8_t _I_Lock_7x8_0[] = {0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; +const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; @@ -478,12 +472,10 @@ const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.fr const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; -const Icon I_quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_quest_7x8}; -const Icon I_unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_unlock_7x8}; -const Icon I_Scanning_dolph_67_61 = {.width=67,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_dolph_67_61}; -const Icon I_Broadcast_dolph_67_61 = {.width=67,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_Broadcast_dolph_67_61}; -const Icon I_lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_lock_7x8}; -const Icon I_Top_frame_128_13 = {.width=128,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Top_frame_128_13}; +const Icon I_Scanning_123x52 = {.width=123,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_123x52}; +const Icon I_Quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Quest_7x8}; +const Icon I_Unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Unlock_7x8}; +const Icon I_Lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_7x8}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; const Icon I_DoorLeft_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_8x56}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index 81cf0232..689ce0d7 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -29,12 +29,10 @@ extern const Icon I_DolphinFirstStart8_56x51; extern const Icon I_DolphinFirstStart7_61x51; extern const Icon I_Flipper_young_80x60; extern const Icon I_DolphinFirstStart3_57x48; -extern const Icon I_quest_7x8; -extern const Icon I_unlock_7x8; -extern const Icon I_Scanning_dolph_67_61; -extern const Icon I_Broadcast_dolph_67_61; -extern const Icon I_lock_7x8; -extern const Icon I_Top_frame_128_13; +extern const Icon I_Scanning_123x52; +extern const Icon I_Quest_7x8; +extern const Icon I_Unlock_7x8; +extern const Icon I_Lock_7x8; extern const Icon I_PassportBottom_128x17; extern const Icon I_DoorLeft_8x56; extern const Icon I_DoorLocked_10x56; diff --git a/assets/icons/GubGHz/Broadcast_dolph_67-61.png b/assets/icons/GubGHz/Broadcast_dolph_67-61.png deleted file mode 100644 index 9864e0857d0be3d8e65500c8aef368b6f8bd4185..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3894 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 diff --git a/assets/icons/GubGHz/Scanning_123x52.png b/assets/icons/GubGHz/Scanning_123x52.png new file mode 100644 index 0000000000000000000000000000000000000000..ec785948d035b717944bc41811f73d190e6fc3bd GIT binary patch literal 1690 zcmaJ?X;2eq7>)>*yJ)S*p|h?~Q6$-f1d>2NNH}5%Lt|z{KrzQc(y-YyStJQ+g^C9Q zSWv-YttjHfh@wyt@GLFhMTjB}M;LSv6%;{^;@J%X_DAW??0&~Q&+|U-`@P@n?x@Hx zJ8Nfa0)b%14d?LjF%^HQmS*_Zy;Prz4^CJ}G`0p!z*2-Nm=GjEMKHicgo!X87D}`~ zG{XJ_!fZF0AR3G2MKHxELKK=XL=B?E*#v@rphhVa%V7)_o@3{?OoMWF~y##kV3^-~Ura#~iQo~#pIF_K28B$0`bDW@qQkN5vj1er#wF+Tj+ z?|%xb1zIIc;=^h*StZ6#E@7!Dl#l0+R;G}k zDeC1D1RjscRj4tcLJV^`ED)C<%48Czw=bJb<4}SjatMt~4q?;jbe~|z8=_EsXfzI; zGR5Vf;$#F?U{hSlXD)k2uBjOiB_5drt7MyCNvH}%fQg)$vYEXwX4ISHN@n&FG$WUU zn<1G__FpGGwS~8jX*%7w_+q;CVFljrD!j4V;}c)t_r;dW2@+`9`eU1O>Hy1H=Z_x? z#)vXQ4`HsunYK6jxY4-M*|zlR`rg;$+V*St8!R`}`J(H(M(Fn4S4n;$pnW-UN$QA` z?fY?KM*pGHedF?8-QC`CtG>sHp2-iZetB?^`cj>4f5g#9o;N06J$3^rWaoX6Zp!iN6AS8ml(v%micb;q2O2KuEfM&;;GfOLnbEbQ;Xh2MB~uUb$O z=Tf34Z;Mngv^s8}xvK?|Q)X5xaeMf&yLz=D);7(;s_;xKaAkeDy_0K?%Yn2|k9C6T z^kdg4x7}!2l%F~e-2N&yKK{I*<bm{PN1M%~EqIS+ z#{g%nih7mt;>v=&E{mA(e4W(c;<>|5`bM6gWBHY@vRSt9LE+^Uhns6zS!2UzZw(cU zoUfWE)n;PLGTwze=xNtR#E5s54 z?u4@P3{ljfm#4cr?==i}&Q~nx+6o_SALMl>7g+8+b*EGr+g0b>QusCdoqSG@XTkT} zJKW>*p7M7!ScsC+I$SWe`PeH**g7LKd+2^e4BT{9(i5Fx*_t#~^L&3q*^<`Bg8SLL zJr^&8Wvz+nlWyNPFyz7qEt>zJmbmY7f19~I|Kz}R|I(kU_SSdG*|X+`TiP_=YR)O9 z%>w2`t#*GaxqGd${KiVYrAK$bi$_|DyT^Fr>F$>+;8w9Tw&Z$d+!FWSfdT)vdK%bz zZxc14Zjp1X%kW^EaVRy?Y1r_3XHB46)J>z~?!08J+0&8}hNJx?^62efuWTu{t@zFL zVZ4jin2pbcGJ}2f!HjR`wC}%p=#A$7DVOR4RjdwPz~ZWrAMHE3V&KiltB9(rl{Yu) zpLzA}yq2xqYW6IxKLj-^F^5Q^3s;lX5 N!3~Mzlm%~0{|8*@s)qmo literal 0 HcmV?d00001 diff --git a/assets/icons/GubGHz/Scanning_dolph_67-61.png b/assets/icons/GubGHz/Scanning_dolph_67-61.png deleted file mode 100644 index 4f9ea8d7d2b73faa929df7707673bb8220010ec8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3518 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 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -struct used for handling SPI info. -*/ -typedef struct { - SPI_HandleTypeDef* spi; - PubSubCallback cb; - void* ctx; -} SpiHandle; - -/* -For transmit/receive data use `spi_xfer` function. - -* `tx_data` and `rx_data` size must be equal (and equal `len`) -* `cb` called after spi operation is completed, `(NULL, ctx)` passed to callback. -*/ -bool spi_xfer( - SPI_HandleTypeDef* spi, - uint8_t* tx_data, - uint8_t* rx_data, - size_t len, - PubSubCallback cb, - void* ctx); - -/* -Blocking verison: -*/ -static inline bool - spi_xfer_block(SPI_HandleTypeDef* spi, uint8_t* tx_data, uint8_t* rx_data, size_t len) { - semaphoreInfo s; - osSemaphore block = createSemaphoreStatic(s); - if(!spi_xfer(spi, tx_data, rx_data, len, RELEASE_SEMAPHORE, (void*)block)) { - osReleaseSemaphore(block); - return false; - } - osWaitSemaphore(block); - return false; -} - -/* -Common implementation of SPI bus: serial interface + CS pin -*/ -typedef struct { - GpioPin* cs; ///< CS pin - ValueMutex* spi; ///< -} SpiBus; - -/* -For dedicated work with one device there is `SpiDevice` entity. -It contains ValueMutex around SpiBus: after you acquire device -you can acquire spi to work with it (don't forget SPI bus is shared -around many device, release it after every transaction as quick as possible). -*/ -typedef struct { - ValueMutex* bus; ///< -} SpiDevice; - -##SPI IRQ device - - /* -Many devices (like CC1101 and NFC) present as SPI bus and IRQ line. -For work with it there is special entity `SpiIrqDevice`. -Use `subscribe_pubsub` for subscribinq to irq events. -*/ - - typedef struct { - ValueMutex* bus; ///< - PubSub* irq; -} SpiIrqDevice; - -/* -Special implementation of SPI bus: serial interface + CS, Res, D/I lines. -*/ -typedef struct { - GpioPin* cs; ///< CS pin - GpioPin* res; ///< reset pin - GpioPin* di; ///< D/I pin - ValueMutex* spi; ///< -} DisplayBus; - -typedef struct { - ValueMutex* bus; ///< -} DisplayDevice; - -/* -# SPI devices (F2) - -* `/dev/sdcard` - SD card SPI, `SpiDevice` -* `/dev/cc1101_bus` - Sub-GHz radio (CC1101), `SpiIrqDevice` -* `/dev/nfc` - NFC (ST25R3916), `SpiIrqDevice` -* `/dev/display` - `DisplayDevice` -* `/dev/spiext` - External SPI (warning! Lock PA4, PA5, PA6, PA7) - -### Application example - -```C -// Be careful, this function called from IRQ context -void handle_irq(void* _arg, void* _ctx) { -} - -void cc1101_example() { - SpiIrqDevice* cc1101_device = open_input("/dev/cc1101_bus"); - if(cc1101_device == NULL) return; // bus not available, critical error - - subscribe_pubsub(cc1101_device->irq, handle_irq, NULL); - - { - // acquire device as device bus - SpiBus* spi_bus = acquire_mutex(cc1101_device->bus, 0); - if(spi_bus == NULL) { - printf("Device busy\n"); - // wait for device - spi_bus = acquire_mutex_block(cc1101_device->bus); - } - - // make transaction - uint8_t request[4] = {0xDE, 0xAD, 0xBE, 0xEF}; - uint8_t response[4]; - - { - SPI_HandleTypeDef* spi = acquire_mutex_block(spi_bus->spi); - - gpio_write(spi_bus->cs, false); - spi_xfer_block(spi, request, response, 4); - gpio_write(spi_bus->cs, true); - - release_mutex(cc1101_device->spi, spi); - } - - // release device (device bus) - release_mutex(cc1101_device->bus, spi_bus); - } -} -``` -*/ - -#ifdef __cplusplus -} -#endif diff --git a/core/furi/common_defines.h b/core/furi/common_defines.h index ceac90ae..011af99e 100644 --- a/core/furi/common_defines.h +++ b/core/furi/common_defines.h @@ -31,3 +31,12 @@ #ifndef COUNT_OF #define COUNT_OF(x) (sizeof(x) / sizeof(x[0])) #endif + +#ifndef FURI_SWAP +#define FURI_SWAP(x, y) \ + do { \ + typeof(x) SWAP = x; \ + x = y; \ + y = SWAP; \ + } while(0) +#endif diff --git a/lib/subghz/protocols/subghz_protocol_came.h b/lib/subghz/protocols/subghz_protocol_came.h index 21cd5eca..ffe96835 100644 --- a/lib/subghz/protocols/subghz_protocol_came.h +++ b/lib/subghz/protocols/subghz_protocol_came.h @@ -22,7 +22,9 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance); * @param encoder - SubGhzProtocolCommonEncoder encoder * @return bool */ -bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder); +bool subghz_protocol_came_send_key( + SubGhzProtocolCame* instance, + SubGhzProtocolCommonEncoder* encoder); /** Reset internal state * @param instance - SubGhzProtocolCame instance @@ -43,6 +45,26 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 */ void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzProtocolCame instance + * @param output - the resulting string + */ void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output); -bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance); + +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzProtocolCame instance + * @return bool + */ +bool subghz_protocol_came_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolCame* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolCame instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_common.h b/lib/subghz/protocols/subghz_protocol_common.h index 79c2a2c0..277f89fa 100644 --- a/lib/subghz/protocols/subghz_protocol_common.h +++ b/lib/subghz/protocols/subghz_protocol_common.h @@ -96,9 +96,30 @@ struct SubGhzProtocolCommonLoad{ uint32_t param3; }; +/** Allocate SubGhzProtocolCommonEncoder + * + * @return SubGhzProtocolCommonEncoder* + */ SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc(); + +/** Free SubGhzProtocolCommonEncoder + * + * @param instance + */ void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance); + +/** Get count repeat left + * + * @param instance - SubGhzProtocolCommonEncoder instance + * @return count repeat left + */ size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance); + +/** Get LevelDuration this encoder step + * + * @param context - SubGhzProtocolCommonEncoder context + * @return LevelDuration this step + */ LevelDuration subghz_protocol_encoder_common_yield(void* context); /** Add data bit to code_found @@ -146,4 +167,11 @@ void subghz_protocol_common_set_callback( */ void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output); +/** Converting a string to a HEX array + * + * @param str - string data + * @param buff - uint8_t* buff + * @param len - size buff + * @return bool + */ bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len); diff --git a/lib/subghz/protocols/subghz_protocol_faac_slh.h b/lib/subghz/protocols/subghz_protocol_faac_slh.h index 43f9d2bf..cfd46061 100644 --- a/lib/subghz/protocols/subghz_protocol_faac_slh.h +++ b/lib/subghz/protocols/subghz_protocol_faac_slh.h @@ -50,4 +50,9 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, */ void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output); +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolFaacSLH instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.h b/lib/subghz/protocols/subghz_protocol_gate_tx.h index b09bb077..79f3b9db 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.h +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.h @@ -43,6 +43,24 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u */ void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzProtocolGateTX instance + * @param output - the resulting string + */ void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output); + +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzProtocolGateTX instance + * @return bool + */ bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolGateTX instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_ido.h b/lib/subghz/protocols/subghz_protocol_ido.h index df03ad0a..10b1ddb0 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.h +++ b/lib/subghz/protocols/subghz_protocol_ido.h @@ -49,4 +49,10 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t * @param output - output string */ void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolIDo instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index 7baead74..875e6002 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -174,15 +174,31 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan instance->common.btn = key_fix >> 28; } -const char* subghz_protocol_keeloq_get_manufacture_name(void* context) { +const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context) { SubGhzProtocolKeeloq* instance = context; subghz_protocol_keeloq_check_remote_controller(instance); return instance->manufacture_name; } -void subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name) { +const char* subghz_protocol_keeloq_get_manufacture_name(void* context) { + SubGhzProtocolKeeloq* instance = context; + return instance->manufacture_name; +} + +bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name) { SubGhzProtocolKeeloq* instance = context; instance->manufacture_name = manufacture_name; + int res = 0; + for + M_EACH( + manufacture_code, + *subghz_keystore_get_data(instance->keystore), + SubGhzKeyArray_t) { + res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); + if(res == 0) return true; + } + instance->manufacture_name = "Unknown"; + return false; } uint64_t subghz_protocol_keeloq_gen_key(void* context) { @@ -232,6 +248,10 @@ bool subghz_protocol_keeloq_send_key( if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(!strcmp(instance->manufacture_name, "Unknown")) { + return false; + } + size_t index = 0; encoder->size_upload = 11 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 4; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; @@ -392,8 +412,7 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp code_found_reverse_lo, instance->common.btn, instance->manufacture_name, - instance->common.serial - ); + instance->common.serial); } void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) { @@ -450,9 +469,7 @@ bool subghz_protocol_keeloq_to_load_protocol_from_file( return loaded; } -void subghz_decoder_keeloq_to_load_protocol( - SubGhzProtocolKeeloq* instance, - void* context) { +void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.h b/lib/subghz/protocols/subghz_protocol_keeloq.h index 6680f52e..1cbacd8c 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.h +++ b/lib/subghz/protocols/subghz_protocol_keeloq.h @@ -18,14 +18,27 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore); */ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance); +/** Find and get manufacture name + * + * @param context - SubGhzProtocolKeeloq context + * @return name - char* manufacture name + */ +const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context); + +/** Get manufacture name + * + * @param context - SubGhzProtocolKeeloq context + * @return name - char* manufacture name + */ const char* subghz_protocol_keeloq_get_manufacture_name(void* context); /** Set manufacture name * * @param manufacture_name - manufacture name * @param context - SubGhzProtocolKeeloq context + * @return bool */ -void subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name); +bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name); /** Get key keeloq * @@ -61,6 +74,24 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui */ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzProtocolKeeloq instance + * @param output - the resulting string + */ void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output); + +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzProtocolKeeloq instance + * @return bool + */ bool subghz_protocol_keeloq_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolKeeloq* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolKeeloq instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.h b/lib/subghz/protocols/subghz_protocol_nero_sketch.h index 82ef3d6e..e8a19a50 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.h +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.h @@ -49,6 +49,24 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool */ void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzProtocolNeroSketch instance + * @param output - the resulting string + */ void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output); + +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzProtocolNeroSketch instance + * @return bool + */ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolNeroSketch instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.h b/lib/subghz/protocols/subghz_protocol_nice_flo.h index 3f76fe89..0f88636d 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.h +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.h @@ -43,6 +43,24 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, */ void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzProtocolNiceFlo instance + * @param output - the resulting string + */ void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output); + +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzProtocolNiceFlo instance + * @return bool + */ bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolNiceFlo instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context); diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.h b/lib/subghz/protocols/subghz_protocol_nice_flor_s.h index 6127f94f..60f7431d 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.h +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.h @@ -50,4 +50,10 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool l * @param output - output string */ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output); + +/** Loading protocol from bin data + * + * @param instance - SubGhzProtocolNiceFlorS instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context); \ No newline at end of file diff --git a/lib/subghz/protocols/subghz_protocol_princeton.h b/lib/subghz/protocols/subghz_protocol_princeton.h index 463d9ada..fdc37a43 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.h +++ b/lib/subghz/protocols/subghz_protocol_princeton.h @@ -56,6 +56,11 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(); */ void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance); +/** Get Te interval protocol + * + * @param context - SubGhzDecoderPrinceton context + * @return Te interval (us) + */ uint16_t subghz_protocol_princeton_get_te(void* context); /** Get upload protocol @@ -90,11 +95,26 @@ void subghz_decoder_princeton_parse( */ void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output); +/** Get a string to save the protocol + * + * @param instance - SubGhzDecoderPrinceton instance + * @param output - the resulting string + */ void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output); -bool subghz_decoder_princeton_to_load_protocol_from_file( - FileWorker* file_worker, - SubGhzDecoderPrinceton* instance); +/** Loading protocol from file + * + * @param file_worker - FileWorker file_worker + * @param instance - SubGhzDecoderPrinceton instance + * @return bool + */ +bool subghz_decoder_princeton_to_load_protocol_from_file(FileWorker* file_worker, SubGhzDecoderPrinceton* instance); + +/** Loading protocol from bin data + * + * @param instance - SubGhzDecoderPrinceton instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_princeton_to_load_protocol( SubGhzDecoderPrinceton* instance, void* context) ; diff --git a/lib/subghz/protocols/subghz_protocol_star_line.c b/lib/subghz/protocols/subghz_protocol_star_line.c index 384ec10c..f8207348 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.c +++ b/lib/subghz/protocols/subghz_protocol_star_line.c @@ -38,12 +38,17 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) { free(instance); } -const char* subghz_protocol_star_line_get_manufacture_name (void* context){ +const char* subghz_protocol_star_line_find_and_get_manufacture_name (void* context){ SubGhzProtocolStarLine* instance = context; subghz_protocol_star_line_check_remote_controller(instance); return instance->manufacture_name; } +const char* subghz_protocol_star_line_get_manufacture_name (void* context){ + SubGhzProtocolStarLine* instance = context; + return instance->manufacture_name; +} + /** Send bit * * @param instance - SubGhzProtocolStarLine instance diff --git a/lib/subghz/protocols/subghz_protocol_star_line.h b/lib/subghz/protocols/subghz_protocol_star_line.h index 840f0344..b1c28dc5 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.h +++ b/lib/subghz/protocols/subghz_protocol_star_line.h @@ -18,6 +18,18 @@ SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore */ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance); +/** Find and get manufacture name + * + * @param context - SubGhzProtocolStarLine context + * @return name - char* manufacture name + */ +const char* subghz_protocol_star_line_find_and_get_manufacture_name(void* context); + +/** Get manufacture name + * + * @param context - SubGhzProtocolStarLine context + * @return name - char* manufacture name + */ const char* subghz_protocol_star_line_get_manufacture_name(void* context); /** Sends the key on the air @@ -53,4 +65,10 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve * @param output - output string */ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output); + +/** Loading protocol from bin data + * + * @param instance - SubGhzDecoderPrinceton instance + * @param context - SubGhzProtocolCommonLoad context + */ void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context); diff --git a/lib/subghz/subghz_keystore.h b/lib/subghz/subghz_keystore.h index 4b10730b..4cd388f5 100644 --- a/lib/subghz/subghz_keystore.h +++ b/lib/subghz/subghz_keystore.h @@ -16,10 +16,28 @@ ARRAY_DEF(SubGhzKeyArray, SubGhzKey, M_POD_OPLIST) typedef struct SubGhzKeystore SubGhzKeystore; +/** Allocate SubGhzKeystore + * + * @return SubGhzKeystore* + */ SubGhzKeystore* subghz_keystore_alloc(); +/** Free SubGhzKeystore + * + * @param instance + */ void subghz_keystore_free(SubGhzKeystore* instance); +/** Loading manufacture key from file + * + * @param instance - SubGhzKeystore instance + * @param filename - const char* full path to the file + */ void subghz_keystore_load(SubGhzKeystore* instance, const char* filename); +/** Get array of keys and names manufacture + * + * @param instance - SubGhzKeystore instance + * @return SubGhzKeyArray_t* + */ SubGhzKeyArray_t* subghz_keystore_get_data(SubGhzKeystore* instance);