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 9864e085..00000000 Binary files a/assets/icons/GubGHz/Broadcast_dolph_67-61.png and /dev/null differ diff --git a/assets/icons/GubGHz/Scanning_123x52.png b/assets/icons/GubGHz/Scanning_123x52.png new file mode 100644 index 00000000..ec785948 Binary files /dev/null and b/assets/icons/GubGHz/Scanning_123x52.png differ 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 4f9ea8d7..00000000 Binary files a/assets/icons/GubGHz/Scanning_dolph_67-61.png and /dev/null differ diff --git a/assets/icons/GubGHz/Top-frame_128-13.png b/assets/icons/GubGHz/Top-frame_128-13.png deleted file mode 100644 index a088656c..00000000 Binary files a/assets/icons/GubGHz/Top-frame_128-13.png and /dev/null differ diff --git a/core/furi-hal/api-spi.h b/core/furi-hal/api-spi.h deleted file mode 100644 index 8640d0d3..00000000 --- a/core/furi-hal/api-spi.h +++ /dev/null @@ -1,144 +0,0 @@ -#include - -#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);