From 8fd411097ec3cd96c5f744008d71529661eea732 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 15 Sep 2021 19:24:19 +0400 Subject: [PATCH] [FL-1758, FL-1790] SubGhz refactoring part 2, fix generation of a new GateTX serial (#696) * WidGet: fix name Multiline String Element * SubGhz: rename SubGhzProtocol to SubGhzParser and bring it up * SubGhz: a new way to navigate in receiver views * SubGhz: fix syntax * WedGet: add forwarding input type to wedget button callback, fix using a callback in an application * SubGhz: add assertions and status checks * SubGhz: fix syntax * [FL-1790] SubGhz: fix GateTX * SubGhz: add 434.42 MHz frequency support * SubGhz: rename type protocol, add decoder stage names * SubGhz: fix navigation through received signals when changing scenes * SubGhz: fix 2-fsk config Co-authored-by: Aleksandr Kutuzov --- applications/gui/modules/widget.c | 8 +- applications/gui/modules/widget.h | 2 +- .../widget_elements/widget_element_button.c | 25 +- .../widget_elements/widget_element_i.h | 7 +- ...ti.c => widget_element_string_multiline.c} | 18 +- applications/nfc/scenes/nfc_scene_delete.c | 7 +- .../nfc/scenes/nfc_scene_device_info.c | 12 +- .../scenes/nfc_scene_read_emv_data_success.c | 10 +- .../subghz/scenes/subghz_scene_receiver.c | 31 +- .../scenes/subghz_scene_receiver_info.c | 50 ++-- .../subghz/scenes/subghz_scene_set_type.c | 5 +- .../subghz/scenes/subghz_scene_transmitter.c | 10 +- applications/subghz/subghz.c | 20 +- applications/subghz/subghz_cli.c | 16 +- applications/subghz/subghz_history.h | 2 - applications/subghz/subghz_i.c | 122 ++++---- applications/subghz/subghz_i.h | 23 +- applications/subghz/views/subghz_receiver.c | 14 +- .../targets/f6/furi-hal/furi-hal-subghz.c | 276 +++++++++-------- .../targets/f7/furi-hal/furi-hal-subghz.c | 278 +++++++++-------- lib/subghz/protocols/subghz_protocol.h | 72 ----- lib/subghz/protocols/subghz_protocol_came.c | 119 ++++---- lib/subghz/protocols/subghz_protocol_common.h | 28 +- .../protocols/subghz_protocol_faac_slh.c | 134 +++++---- .../protocols/subghz_protocol_gate_tx.c | 143 +++++---- lib/subghz/protocols/subghz_protocol_ido.c | 45 +-- lib/subghz/protocols/subghz_protocol_keeloq.c | 41 +-- .../protocols/subghz_protocol_nero_radio.c | 49 +-- .../protocols/subghz_protocol_nero_sketch.c | 192 ++++++------ .../protocols/subghz_protocol_nice_flo.c | 118 ++++---- .../protocols/subghz_protocol_nice_flor_s.c | 105 ++++--- .../protocols/subghz_protocol_princeton.c | 36 ++- .../protocols/subghz_protocol_star_line.c | 282 ++++++++++-------- .../subghz_protocol.c => subghz_parser.c} | 67 +++-- lib/subghz/subghz_parser.h | 72 +++++ 35 files changed, 1326 insertions(+), 1113 deletions(-) rename applications/gui/modules/widget_elements/{widget_element_string_multi.c => widget_element_string_multiline.c} (70%) delete mode 100644 lib/subghz/protocols/subghz_protocol.h rename lib/subghz/{protocols/subghz_protocol.c => subghz_parser.c} (82%) create mode 100644 lib/subghz/subghz_parser.h diff --git a/applications/gui/modules/widget.c b/applications/gui/modules/widget.c index 4b561260..92ca9133 100755 --- a/applications/gui/modules/widget.c +++ b/applications/gui/modules/widget.c @@ -118,7 +118,7 @@ static void widget_add_element(Widget* widget, WidgetElement* element) { }); } -void widget_add_string_multi_element( +void widget_add_string_multiline_element( Widget* widget, uint8_t x, uint8_t y, @@ -127,9 +127,9 @@ void widget_add_string_multi_element( Font font, const char* text) { furi_assert(widget); - WidgetElement* string_multi_element = - widget_element_string_multi_create(x, y, horizontal, vertical, font, text); - widget_add_element(widget, string_multi_element); + WidgetElement* string_multiline_element = + widget_element_string_multiline_create(x, y, horizontal, vertical, font, text); + widget_add_element(widget, string_multiline_element); } void widget_add_string_element( diff --git a/applications/gui/modules/widget.h b/applications/gui/modules/widget.h index 943e63c4..9a335bce 100755 --- a/applications/gui/modules/widget.h +++ b/applications/gui/modules/widget.h @@ -34,7 +34,7 @@ View* widget_get_view(Widget* widget); * @param vertical - Align instance * @param font Font instance */ -void widget_add_string_multi_element( +void widget_add_string_multiline_element( Widget* widget, uint8_t x, uint8_t y, diff --git a/applications/gui/modules/widget_elements/widget_element_button.c b/applications/gui/modules/widget_elements/widget_element_button.c index 4b8517e0..2fbfb892 100644 --- a/applications/gui/modules/widget_elements/widget_element_button.c +++ b/applications/gui/modules/widget_elements/widget_element_button.c @@ -32,26 +32,15 @@ static bool gui_button_input(InputEvent* event, WidgetElement* element) { if(model->callback == NULL) return consumed; - if(event->key == InputKeyOk && event->type == InputTypePress && - model->button_type == GuiButtonTypeCenter) { - model->callback(GuiButtonTypeCenterPress, model->context); + if((model->button_type == GuiButtonTypeLeft) && (event->key == InputKeyLeft)) { + model->callback(model->button_type, event->type, model->context); consumed = true; - } else if( - event->key == InputKeyOk && event->type == InputTypeRelease && - model->button_type == GuiButtonTypeCenter) { - model->callback(GuiButtonTypeCenterRelease, model->context); + } else if((model->button_type == GuiButtonTypeRight) && (event->key == InputKeyRight)) { + model->callback(model->button_type, event->type, model->context); + consumed = true; + } else if((model->button_type == GuiButtonTypeCenter) && (event->key == InputKeyOk)) { + model->callback(model->button_type, event->type, model->context); consumed = true; - } else if(event->type == InputTypeShort) { - if((model->button_type == GuiButtonTypeLeft) && (event->key == InputKeyLeft)) { - model->callback(model->button_type, model->context); - consumed = true; - } else if((model->button_type == GuiButtonTypeRight) && (event->key == InputKeyRight)) { - model->callback(model->button_type, model->context); - consumed = true; - } else if((model->button_type == GuiButtonTypeCenter) && (event->key == InputKeyOk)) { - model->callback(model->button_type, model->context); - consumed = true; - } } return consumed; diff --git a/applications/gui/modules/widget_elements/widget_element_i.h b/applications/gui/modules/widget_elements/widget_element_i.h index d99e349f..2930eb1c 100755 --- a/applications/gui/modules/widget_elements/widget_element_i.h +++ b/applications/gui/modules/widget_elements/widget_element_i.h @@ -1,16 +1,15 @@ #pragma once #include #include +#include typedef enum { GuiButtonTypeLeft, GuiButtonTypeCenter, GuiButtonTypeRight, - GuiButtonTypeCenterPress, - GuiButtonTypeCenterRelease, } GuiButtonType; -typedef void (*ButtonCallback)(GuiButtonType result, void* context); +typedef void (*ButtonCallback)(GuiButtonType result, InputType type, void* context); typedef struct WidgetElement WidgetElement; typedef struct Widget Widget; @@ -31,7 +30,7 @@ struct WidgetElement { }; /* Create multi string element */ -WidgetElement* widget_element_string_multi_create( +WidgetElement* widget_element_string_multiline_create( uint8_t x, uint8_t y, Align horizontal, diff --git a/applications/gui/modules/widget_elements/widget_element_string_multi.c b/applications/gui/modules/widget_elements/widget_element_string_multiline.c similarity index 70% rename from applications/gui/modules/widget_elements/widget_element_string_multi.c rename to applications/gui/modules/widget_elements/widget_element_string_multiline.c index ad9c58f5..f37eb3fc 100644 --- a/applications/gui/modules/widget_elements/widget_element_string_multi.c +++ b/applications/gui/modules/widget_elements/widget_element_string_multiline.c @@ -9,12 +9,12 @@ typedef struct { Align vertical; Font font; string_t text; -} GuiStringMultiModel; +} GuiStringMultiLineModel; -static void gui_string_multi_draw(Canvas* canvas, WidgetElement* element) { +static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { furi_assert(canvas); furi_assert(element); - GuiStringMultiModel* model = element->model; + GuiStringMultiLineModel* model = element->model; if(string_size(model->text)) { canvas_set_font(canvas, model->font); @@ -28,16 +28,16 @@ static void gui_string_multi_draw(Canvas* canvas, WidgetElement* element) { } } -static void gui_string_multi_free(WidgetElement* gui_string) { +static void gui_string_multiline_free(WidgetElement* gui_string) { furi_assert(gui_string); - GuiStringMultiModel* model = gui_string->model; + GuiStringMultiLineModel* model = gui_string->model; string_clear(model->text); free(gui_string->model); free(gui_string); } -WidgetElement* widget_element_string_multi_create( +WidgetElement* widget_element_string_multiline_create( uint8_t x, uint8_t y, Align horizontal, @@ -47,7 +47,7 @@ WidgetElement* widget_element_string_multi_create( furi_assert(text); // Allocate and init model - GuiStringMultiModel* model = furi_alloc(sizeof(GuiStringMultiModel)); + GuiStringMultiLineModel* model = furi_alloc(sizeof(GuiStringMultiLineModel)); model->x = x; model->y = y; model->horizontal = horizontal; @@ -59,8 +59,8 @@ WidgetElement* widget_element_string_multi_create( WidgetElement* gui_string = furi_alloc(sizeof(WidgetElement)); gui_string->parent = NULL; gui_string->input = NULL; - gui_string->draw = gui_string_multi_draw; - gui_string->free = gui_string_multi_free; + gui_string->draw = gui_string_multiline_draw; + gui_string->free = gui_string_multiline_free; gui_string->model = model; return gui_string; diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c index 9098759b..5c6fe254 100755 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -1,9 +1,10 @@ #include "../nfc_i.h" -void nfc_scene_delete_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_delete_on_enter(void* context) { diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 032834c5..43082dcf 100755 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -7,9 +7,11 @@ enum { NfcSceneDeviceInfoData, }; -void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_device_info_widget_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) { @@ -22,9 +24,11 @@ void nfc_scene_device_info_text_box_callback(void* context) { view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); } -void nfc_scene_device_info_bank_card_callback(GuiButtonType result, void* context) { +void nfc_scene_device_info_bank_card_callback(GuiButtonType result, InputType type, void* context) { Nfc* nfc = context; - view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); + } } void nfc_scene_device_info_on_enter(void* context) { diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c index 927adb42..c0b61111 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -1,10 +1,14 @@ #include "../nfc_i.h" #include "../helpers/nfc_emv_parser.h" -void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) { +void nfc_scene_read_emv_data_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_read_emv_data_success_on_enter(void* context) { diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c index b829efc1..ffe510aa 100644 --- a/applications/subghz/scenes/subghz_scene_receiver.c +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -46,7 +46,7 @@ void subghz_scene_add_to_history_callback(SubGhzProtocolCommon* parser, void* co if(subghz_history_add_to_history( subghz->txrx->history, parser, subghz->txrx->frequency, subghz->txrx->preset)) { - subghz_protocol_reset(subghz->txrx->protocol); + subghz_parser_reset(subghz->txrx->parser); string_clean(str_buff); subghz_history_get_text_item_menu( subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); @@ -79,23 +79,18 @@ const void subghz_scene_receiver_on_enter(void* context) { string_clear(str_buff); subghz_scene_receiver_update_statusbar(subghz); subghz_receiver_set_callback(subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); - subghz_protocol_enable_dump( - subghz->txrx->protocol, subghz_scene_add_to_history_callback, subghz); + subghz_parser_enable_dump(subghz->txrx->parser, subghz_scene_add_to_history_callback, subghz); subghz->state_notifications = NOTIFICATION_RX_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - //subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); }; - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_begin(subghz->txrx->preset); - subghz_rx(subghz->txrx->worker, subghz->txrx->frequency); - subghz->txrx->txrx_state = SubGhzTxRxStateRx; - } - if(subghz->txrx->idx_menu_chosen != 0) { - subghz_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); + if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { + subghz_begin(subghz, subghz->txrx->preset); + subghz_rx(subghz, subghz->txrx->frequency); } + subghz_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver); } @@ -108,16 +103,15 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event case SubghzReceverEventBack: // Stop CC1101 Rx if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); + subghz_sleep(subghz); }; subghz_history_clean(subghz->txrx->history); subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; subghz->txrx->idx_menu_chosen = 0; - subghz_protocol_enable_dump(subghz->txrx->protocol, NULL, subghz); + subghz_parser_enable_dump(subghz->txrx->parser, NULL, subghz); scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); return true; @@ -129,6 +123,7 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event break; case SubghzReceverEventConfig: subghz->state_notifications = NOTIFICATION_IDLE_STATE; + subghz->txrx->idx_menu_chosen = subghz_receiver_get_idx_menu(subghz->subghz_receiver); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig); return true; break; @@ -137,7 +132,7 @@ const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz->txrx); + subghz_hopper_update(subghz); subghz_scene_receiver_update_statusbar(subghz); } diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c index c69ddaa8..8f266337 100644 --- a/applications/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/subghz/scenes/subghz_scene_receiver_info.c @@ -1,15 +1,31 @@ #include "../subghz_i.h" -void subghz_scene_receiver_info_callback(GuiButtonType result, void* context) { +typedef enum { + SubGhzSceneReceiverInfoCustomEventTxStart, + SubGhzSceneReceiverInfoCustomEventTxStop, + SubGhzSceneReceiverInfoCustomEventSave, +} SubGhzSceneReceiverInfoCustomEvent; + +void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); SubGhz* subghz = context; - view_dispatcher_send_custom_event(subghz->view_dispatcher, result); + + if((result == GuiButtonTypeCenter) && (type == InputTypePress)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventTxStart); + } else if((result == GuiButtonTypeCenter) && (type == InputTypeRelease)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventTxStop); + } else if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzSceneReceiverInfoCustomEventSave); + } } static bool subghz_scene_receiver_info_update_parser(void* context) { SubGhz* subghz = context; - subghz->txrx->protocol_result = subghz_protocol_get_by_name( - subghz->txrx->protocol, + subghz->txrx->protocol_result = subghz_parser_get_by_name( + subghz->txrx->parser, subghz_history_get_name(subghz->txrx->history, subghz->txrx->idx_menu_chosen)); if(subghz->txrx->protocol_result->to_load_protocol != NULL) { @@ -51,7 +67,7 @@ const void subghz_scene_receiver_info_on_enter(void* context) { string_t text; string_init(text); subghz->txrx->protocol_result->to_string(subghz->txrx->protocol_result, text); - widget_add_string_multi_element( + widget_add_string_multiline_element( subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); string_clear(text); @@ -83,52 +99,46 @@ const void subghz_scene_receiver_info_on_enter(void* context) { const bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeCenterPress) { + if(event.event == SubGhzSceneReceiverInfoCustomEventTxStart) { //CC1101 Stop RX -> Start TX subghz->state_notifications = NOTIFICATION_TX_STATE; if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { subghz->txrx->hopper_state = SubGhzHopperStatePause; } if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - //subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); } if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; } if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { subghz_tx_start(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; } return true; - } else if(event.event == GuiButtonTypeCenterRelease) { + } else if(event.event == SubGhzSceneReceiverInfoCustomEventTxStop) { //CC1101 Stop Tx -> Start RX subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_begin(subghz->txrx->preset); - subghz_rx(subghz->txrx->worker, subghz->txrx->frequency); - subghz->txrx->txrx_state = SubGhzTxRxStateRx; + subghz_begin(subghz, subghz->txrx->preset); + subghz_rx(subghz, subghz->txrx->frequency); } if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { subghz->txrx->hopper_state = SubGhzHopperStateRunnig; } subghz->state_notifications = NOTIFICATION_RX_STATE; return true; - } else if(event.event == GuiButtonTypeRight) { + } else if(event.event == SubGhzSceneReceiverInfoCustomEventSave) { //CC1101 Stop RX -> Save subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { subghz->txrx->hopper_state = SubGhzHopperStateOFF; } if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); + subghz_sleep(subghz); } if(!subghz_scene_receiver_info_update_parser(subghz)) { return false; @@ -141,7 +151,7 @@ const bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->txrx->hopper_state != SubGhzHopperStateOFF) { - subghz_hopper_update(subghz->txrx); + subghz_hopper_update(subghz); } switch(subghz->state_notifications) { case NOTIFICATION_TX_STATE: diff --git a/applications/subghz/scenes/subghz_scene_set_type.c b/applications/subghz/scenes/subghz_scene_set_type.c index c506a5c7..5993512b 100644 --- a/applications/subghz/scenes/subghz_scene_set_type.c +++ b/applications/subghz/scenes/subghz_scene_set_type.c @@ -15,8 +15,7 @@ enum SubmenuIndex { bool subghz_scene_set_type_submenu_to_find_protocol(void* context, const char* protocol_name) { SubGhz* subghz = context; - subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, protocol_name); + subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, protocol_name); if(subghz->txrx->protocol_result == NULL) { string_set(subghz->error_str, "Protocol not found"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); @@ -142,7 +141,7 @@ const bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event case SubmenuIndexGateTX: if(subghz_scene_set_type_submenu_to_find_protocol(subghz, "GateTX")) { subghz->txrx->protocol_result->code_last_count_bit = 24; - key = (key & 0x00F0FFFF) | 0xF << 16; //btn 0xF, 0xC, 0xA, 0x6 + key = (key & 0x00F0FF00) | 0xF << 16 | 0x40; //btn 0xF, 0xC, 0xA, 0x6 (?) subghz->txrx->protocol_result->code_last_found = subghz_protocol_common_reverse_key( key, subghz->txrx->protocol_result->code_last_count_bit); diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index 349b583f..8e743250 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -70,21 +70,19 @@ const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent ev if(event.event == SubghzTransmitterEventSendStart) { subghz->state_notifications = NOTIFICATION_TX_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(subghz->txrx->worker); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_rx_end(subghz); } - if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + if((subghz->txrx->txrx_state == SubGhzTxRxStateIdle) || + (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { subghz_tx_start(subghz); subghz_scene_transmitter_update_data_show(subghz); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; } return true; } else if(event.event == SubghzTransmitterEventSendStop) { subghz->state_notifications = NOTIFICATION_IDLE_STATE; if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { subghz_tx_stop(subghz); - subghz_sleep(); - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz_sleep(subghz); } return true; } else if(event.event == SubghzTransmitterEventBack) { diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 5b356ab1..02da799d 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -7,6 +7,7 @@ const char* const subghz_frequencies_text[] = { "387.00", "433.08", "433.92", + "434.42", "434.78", "438.90", "464.00", @@ -26,6 +27,7 @@ const uint32_t subghz_frequencies[] = { 387000000, 433075000, /* LPD433 first */ 433920000, /* LPD433 mid */ + 434420000, 434775000, /* LPD433 last channels */ 438900000, 464000000, @@ -156,24 +158,24 @@ SubGhz* subghz_alloc() { subghz->txrx = furi_alloc(sizeof(SubGhzTxRx)); subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92]; subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; - subghz->txrx->txrx_state = SubGhzTxRxStateIdle; + subghz->txrx->txrx_state = SubGhzTxRxStateSleep; subghz->txrx->hopper_state = SubGhzHopperStateOFF; subghz->txrx->history = subghz_history_alloc(); subghz->txrx->worker = subghz_worker_alloc(); - subghz->txrx->protocol = subghz_protocol_alloc(); + subghz->txrx->parser = subghz_parser_alloc(); subghz_worker_set_overrun_callback( - subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset); + subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_parser_reset); subghz_worker_set_pair_callback( - subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); - subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->protocol); + subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_parse); + subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->parser); //Init Error_str string_init(subghz->error_str); - subghz_protocol_load_keeloq_file(subghz->txrx->protocol, "/ext/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file(subghz->txrx->protocol, "/ext/subghz/nice_floor_s_rx"); + subghz_parser_load_keeloq_file(subghz->txrx->parser, "/ext/subghz/keeloq_mfcodes"); + subghz_parser_load_nice_flor_s_file(subghz->txrx->parser, "/ext/subghz/nice_floor_s_rx"); - //subghz_protocol_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); + //subghz_parser_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); return subghz; } @@ -232,7 +234,7 @@ void subghz_free(SubGhz* subghz) { subghz->gui = NULL; //Worker & Protocol & History - subghz_protocol_free(subghz->txrx->protocol); + subghz_parser_free(subghz->txrx->parser); subghz_worker_free(subghz->txrx->worker); subghz_history_free(subghz->txrx->history); free(subghz->txrx); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index e5da483e..46149d4e 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -205,10 +205,10 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); furi_check(instance->stream); - SubGhzProtocol* protocol = subghz_protocol_alloc(); - 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); + SubGhzParser* parser = subghz_parser_alloc(); + subghz_parser_load_keeloq_file(parser, "/ext/subghz/keeloq_mfcodes"); + subghz_parser_load_nice_flor_s_file(parser, "/ext/subghz/nice_floor_s_rx"); + subghz_parser_enable_dump_text(parser, subghz_cli_command_rx_text_callback, instance); // Configure radio furi_hal_subghz_reset(); @@ -228,11 +228,11 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { printf("."); - subghz_protocol_reset(protocol); + subghz_parser_reset(parser); } else { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); - subghz_protocol_parse(protocol, level, duration); + subghz_parser_parse(parser, level, duration); } } } @@ -244,7 +244,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { printf("\r\nPackets recieved %u\r\n", instance->packet_count); // Cleanup - subghz_protocol_free(protocol); + subghz_parser_free(parser); vStreamBufferDelete(instance->stream); free(instance); } diff --git a/applications/subghz/subghz_history.h b/applications/subghz/subghz_history.h index 406c1cee..59655188 100644 --- a/applications/subghz/subghz_history.h +++ b/applications/subghz/subghz_history.h @@ -112,5 +112,3 @@ bool subghz_history_add_to_history( * @return SubGhzProtocolCommonLoad* */ SubGhzProtocolCommonLoad* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx); - -void subghz_hopper_update(void* context); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 757757e8..9a52586a 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -10,19 +10,23 @@ #include "../notification/notification.h" #include "views/subghz_receiver.h" -void subghz_begin(FuriHalSubGhzPreset preset) { +void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { + furi_assert(subghz); furi_hal_subghz_reset(); furi_hal_subghz_idle(); furi_hal_subghz_load_preset(preset); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -uint32_t subghz_rx(void* context, uint32_t frequency) { - furi_assert(context); +uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { + furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { furi_crash(NULL); } - SubGhzWorker* worker = context; + furi_assert( + subghz->txrx->txrx_state != SubGhzTxRxStateRx && + subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); @@ -30,45 +34,54 @@ uint32_t subghz_rx(void* context, uint32_t frequency) { furi_hal_subghz_flush_rx(); furi_hal_subghz_rx(); - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, worker); - subghz_worker_start(worker); + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->txrx->worker); + subghz_worker_start(subghz->txrx->worker); + subghz->txrx->txrx_state = SubGhzTxRxStateRx; return value; } -uint32_t subghz_tx(uint32_t frequency) { +uint32_t subghz_tx(SubGhz* subghz, uint32_t frequency) { + furi_assert(subghz); if(!furi_hal_subghz_is_frequency_valid(frequency)) { furi_crash(NULL); } + furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, true); furi_hal_subghz_tx(); + subghz->txrx->txrx_state = SubGhzTxRxStateTx; return value; } -void subghz_idle(void) { +void subghz_idle(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -void subghz_rx_end(void* context) { - furi_assert(context); - SubGhzWorker* worker = context; - - if(subghz_worker_is_running(worker)) { - subghz_worker_stop(worker); +void subghz_rx_end(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateRx); + if(subghz_worker_is_running(subghz->txrx->worker)) { + subghz_worker_stop(subghz->txrx->worker); furi_hal_subghz_stop_async_rx(); } furi_hal_subghz_idle(); + subghz->txrx->txrx_state = SubGhzTxRxStateIdle; } -void subghz_sleep(void) { +void subghz_sleep(SubGhz* subghz) { + furi_assert(subghz); furi_hal_subghz_sleep(); + subghz->txrx->txrx_state = SubGhzTxRxStateSleep; } -void subghz_frequency_preset_to_str(void* context, string_t output) { - furi_assert(context); - SubGhz* subghz = context; +static void subghz_frequency_preset_to_str(SubGhz* subghz, string_t output) { + furi_assert(subghz); + string_cat_printf( output, "Frequency: %d\n" @@ -77,9 +90,9 @@ void subghz_frequency_preset_to_str(void* context, string_t output) { (int)subghz->txrx->preset); } -void subghz_tx_start(void* context) { - furi_assert(context); - SubGhz* subghz = context; +void subghz_tx_start(SubGhz* subghz) { + furi_assert(subghz); + subghz->txrx->encoder = subghz_protocol_encoder_common_alloc(); subghz->txrx->encoder->repeat = 200; //max repeat with the button held down //get upload @@ -87,14 +100,14 @@ void subghz_tx_start(void* context) { if(subghz->txrx->protocol_result->get_upload_protocol( subghz->txrx->protocol_result, subghz->txrx->encoder)) { if(subghz->txrx->preset) { - subghz_begin(subghz->txrx->preset); + subghz_begin(subghz, subghz->txrx->preset); } else { - subghz_begin(FuriHalSubGhzPresetOok270Async); + subghz_begin(subghz, FuriHalSubGhzPresetOok270Async); } if(subghz->txrx->frequency) { - subghz_tx(subghz->txrx->frequency); + subghz_tx(subghz, subghz->txrx->frequency); } else { - subghz_tx(433920000); + subghz_tx(subghz, 433920000); } //Start TX @@ -104,15 +117,15 @@ void subghz_tx_start(void* context) { } } -void subghz_tx_stop(void* context) { - furi_assert(context); - SubGhz* subghz = context; +void subghz_tx_stop(SubGhz* subghz) { + furi_assert(subghz); + furi_assert(subghz->txrx->txrx_state == SubGhzTxRxStateTx); //Stop TX furi_hal_subghz_stop_async_tx(); subghz_protocol_encoder_common_free(subghz->txrx->encoder); - furi_hal_subghz_idle(); + subghz_idle(subghz); //if protocol dynamic then we save the last upload - if(subghz->txrx->protocol_result->type_protocol == TYPE_PROTOCOL_DYNAMIC) { + if(subghz->txrx->protocol_result->type_protocol == SubGhzProtocolCommonTypeDynamic) { subghz_save_protocol_to_file(subghz, subghz->text_store); } notification_message(subghz->notifications, &sequence_reset_red); @@ -164,7 +177,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { // strlen("Protocol: ") = 10 string_right(temp_str, 10); subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, string_get_cstr(temp_str)); + subghz_parser_get_by_name(subghz->txrx->parser, string_get_cstr(temp_str)); if(subghz->txrx->protocol_result == NULL) { break; } @@ -186,10 +199,10 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { return loaded; } -bool subghz_save_protocol_to_file(void* context, const char* dev_name) { - furi_assert(context); - SubGhz* subghz = context; +bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name) { + furi_assert(subghz); furi_assert(subghz->txrx->protocol_result); + FileWorker* file_worker = file_worker_alloc(false); string_t dev_file_name; string_init(dev_file_name); @@ -308,7 +321,7 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { // strlen("Protocol: ") = 10 string_right(temp_str, 10); subghz->txrx->protocol_result = - subghz_protocol_get_by_name(subghz->txrx->protocol, string_get_cstr(temp_str)); + subghz_parser_get_by_name(subghz->txrx->parser, string_get_cstr(temp_str)); if(subghz->txrx->protocol_result == NULL) { break; } @@ -342,11 +355,10 @@ uint32_t subghz_random_serial(void) { return (uint32_t)rand(); } -void subghz_hopper_update(void* context) { - furi_assert(context); - SubGhzTxRx* txrx = context; +void subghz_hopper_update(SubGhz* subghz) { + furi_assert(subghz); - switch(txrx->hopper_state) { + switch(subghz->txrx->hopper_state) { case SubGhzHopperStateOFF: return; break; @@ -354,8 +366,8 @@ void subghz_hopper_update(void* context) { return; break; case SubGhzHopperStateRSSITimeOut: - if(txrx->hopper_timeout != 0) { - txrx->hopper_timeout--; + if(subghz->txrx->hopper_timeout != 0) { + subghz->txrx->hopper_timeout--; return; } break; @@ -363,35 +375,33 @@ void subghz_hopper_update(void* context) { break; } float rssi = -127.0f; - if(txrx->hopper_state != SubGhzHopperStateRSSITimeOut) { + if(subghz->txrx->hopper_state != SubGhzHopperStateRSSITimeOut) { // See RSSI Calculation timings in CC1101 17.3 RSSI rssi = furi_hal_subghz_get_rssi(); // Stay if RSSI is high enough if(rssi > -90.0f) { - txrx->hopper_timeout = 10; - txrx->hopper_state = SubGhzHopperStateRSSITimeOut; + subghz->txrx->hopper_timeout = 10; + subghz->txrx->hopper_state = SubGhzHopperStateRSSITimeOut; return; } } else { - txrx->hopper_state = SubGhzHopperStateRunnig; + subghz->txrx->hopper_state = SubGhzHopperStateRunnig; } // Select next frequency - if(txrx->hopper_idx_frequency < subghz_hopper_frequencies_count - 1) { - txrx->hopper_idx_frequency++; + if(subghz->txrx->hopper_idx_frequency < subghz_hopper_frequencies_count - 1) { + subghz->txrx->hopper_idx_frequency++; } else { - txrx->hopper_idx_frequency = 0; + subghz->txrx->hopper_idx_frequency = 0; } - if(txrx->txrx_state == SubGhzTxRxStateRx) { - subghz_rx_end(txrx->worker); - txrx->txrx_state = SubGhzTxRxStateIdle; + if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) { + subghz_rx_end(subghz); }; - if(txrx->txrx_state == SubGhzTxRxStateIdle) { - subghz_protocol_reset(txrx->protocol); - txrx->frequency = subghz_hopper_frequencies[txrx->hopper_idx_frequency]; - subghz_rx(txrx->worker, txrx->frequency); - txrx->txrx_state = SubGhzTxRxStateRx; + if(subghz->txrx->txrx_state == SubGhzTxRxStateIdle) { + subghz_parser_reset(subghz->txrx->parser); + subghz->txrx->frequency = subghz_hopper_frequencies[subghz->txrx->hopper_idx_frequency]; + subghz_rx(subghz, subghz->txrx->frequency); } } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index 9d088dc6..eecf98d3 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -22,7 +22,8 @@ #include #include -#include + +#include #include #include "subghz_history.h" @@ -47,6 +48,7 @@ typedef enum { SubGhzTxRxStateIdle, SubGhzTxRxStateRx, SubGhzTxRxStateTx, + SubGhzTxRxStateSleep, } SubGhzTxRxState; /** SubGhzHopperState state */ @@ -59,7 +61,7 @@ typedef enum { struct SubGhzTxRx { SubGhzWorker* worker; - SubGhzProtocol* protocol; + SubGhzParser* parser; SubGhzProtocolCommon* protocol_result; SubGhzProtocolCommonEncoder* encoder; uint32_t frequency; @@ -115,15 +117,14 @@ typedef enum { SubGhzViewTestPacket, } SubGhzView; -void subghz_begin(FuriHalSubGhzPreset preset); -uint32_t subghz_rx(void* context, uint32_t frequency); -uint32_t subghz_tx(uint32_t frequency); -void subghz_idle(void); -void subghz_rx_end(void* context); -void subghz_sleep(void); -void subghz_tx_start(void* context); -void subghz_tx_stop(void* context); +void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset); +uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); +void subghz_rx_end(SubGhz* subghz); +void subghz_sleep(SubGhz* subghz); +void subghz_tx_start(SubGhz* subghz); +void subghz_tx_stop(SubGhz* subghz); bool subghz_key_load(SubGhz* subghz, const char* file_path); -bool subghz_save_protocol_to_file(void* context, const char* dev_name); +bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name); bool subghz_load_protocol_from_file(SubGhz* subghz); uint32_t subghz_random_serial(void); +void subghz_hopper_update(SubGhz* subghz); diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c index 4abf8225..26aec5e7 100644 --- a/applications/subghz/views/subghz_receiver.c +++ b/applications/subghz/views/subghz_receiver.c @@ -29,9 +29,9 @@ struct SubGhzReceiverHistory { typedef struct SubGhzReceiverHistory SubGhzReceiverHistory; static const Icon* ReceiverItemIcons[] = { - [TYPE_PROTOCOL_UNKNOWN] = &I_Quest_7x8, - [TYPE_PROTOCOL_STATIC] = &I_Unlock_7x8, - [TYPE_PROTOCOL_DYNAMIC] = &I_Lock_7x8, + [SubGhzProtocolCommonTypeUnknown] = &I_Quest_7x8, + [SubGhzProtocolCommonTypeStatic] = &I_Unlock_7x8, + [SubGhzProtocolCommonTypeDynamic] = &I_Lock_7x8, }; struct SubghzReceiver { @@ -90,7 +90,13 @@ void subghz_receiver_add_item_to_menu( SubGhzReceiverMenuItemArray_push_raw(model->history->data); string_init_set_str(item_menu->item_str, name); item_menu->type = type; - model->history_item++; + if((model->idx == model->history_item - 1)) { + model->history_item++; + model->idx++; + } else { + model->history_item++; + } + return true; }); subghz_receiver_update_offset(subghz_receiver); diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index c200fc60..4d1f0cbf 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -15,166 +15,174 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x67 }, // Rx BW filter is 270.833333kHz + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz - + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz + /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x88 }, - { CC1101_TEST1, 0x31 }, - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x88}, + {CC1101_TEST1, 0x31}, + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { - // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0xF8 }, - { CC1101_MDMCFG1, 0x00 }, // No preamble/sync - { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud - { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, + {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud + {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -184,8 +192,7 @@ static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 0x00, @@ -195,6 +202,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00 + }; void furi_hal_subghz_init() { @@ -217,11 +225,13 @@ void furi_hal_subghz_init() { // GD0 low cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); - while(hal_gpio_read(&gpio_cc1101_g0) != false); + while(hal_gpio_read(&gpio_cc1101_g0) != false) + ; // GD0 high cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(hal_gpio_read(&gpio_cc1101_g0) != true); + while(hal_gpio_read(&gpio_cc1101_g0) != true) + ; // Reset GD0 to floating state cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); @@ -257,8 +267,7 @@ void furi_hal_subghz_dump_state() { printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", cc1101_get_partnumber(device), - cc1101_get_version(device) - ); + cc1101_get_version(device)); furi_hal_spi_device_return(device); } @@ -266,10 +275,10 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { if(preset == FuriHalSubGhzPresetOok650Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPresetOok270Async){ + } else if(preset == FuriHalSubGhzPresetOok270Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); }else { @@ -289,7 +298,7 @@ void furi_hal_subghz_load_registers(const uint8_t data[][2]) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_reset(device); uint32_t i = 0; - while (data[i][0]) { + while(data[i][0]) { cc1101_write_reg(device, data[i][0], data[i][1]); i++; } @@ -401,7 +410,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { while(true) { CC1101Status status = cc1101_get_status(device); - if (status.STATE == CC1101StateIDLE) break; + if(status.STATE == CC1101StateIDLE) break; } furi_hal_spi_device_return(device); @@ -411,16 +420,16 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - if (path == FuriHalSubGhzPath433) { + if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPath315) { + } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - } else if (path == FuriHalSubGhzPath868) { + } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPathIsolate) { + } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); } else { @@ -438,24 +447,25 @@ static void furi_hal_subghz_capture_ISR() { if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(true, furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + true, + furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } // Channel 2 if(LL_TIM_IsActiveFlag_CC2(TIM2)) { LL_TIM_ClearFlag_CC2(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + false, + LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } } - void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_hal_subghz_state = SubGhzStateAsyncRx; @@ -463,12 +473,13 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -498,7 +509,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Interrupts and channels @@ -508,7 +519,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Start timer @@ -534,8 +545,8 @@ void furi_hal_subghz_stop_async_rx() { } #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) -#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) -#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 typedef struct { uint32_t* buffer; @@ -547,12 +558,13 @@ typedef struct { static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { - while (samples > 0) { + while(samples > 0) { bool is_odd = samples % 2; - LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); - if (level_duration_is_reset(ld)) { + LevelDuration ld = + furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if(level_duration_is_reset(ld)) { // One more even sample required to end at low level - if (is_odd) { + if(is_odd) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -560,7 +572,7 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { break; } else { // Inject guard time if level is incorrect - if (is_odd == level_duration_get_level(ld)) { + if(is_odd == level_duration_get_level(ld)) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -579,21 +591,24 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { static void furi_hal_subghz_async_tx_dma_isr() { furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); - if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } - if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + if(LL_DMA_IsActiveFlag_TC1(DMA1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } } static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { LL_TIM_ClearFlag_UPDATE(TIM2); - if (LL_TIM_GetAutoReload(TIM2) == 0) { - if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + if(LL_TIM_GetAutoReload(TIM2) == 0) { + if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; @@ -612,15 +627,18 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_state = SubGhzStateAsyncTx; - furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); + furi_hal_subghz_async_tx.buffer = + furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); // Configure DMA LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_CIRCULAR; @@ -632,7 +650,8 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr( + DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -640,7 +659,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* // Configure TIM2 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 1000; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -672,7 +691,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_tx(); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); LL_TIM_SetCounter(TIM2, 0); @@ -685,10 +704,9 @@ bool furi_hal_subghz_is_async_tx_complete() { void furi_hal_subghz_stop_async_tx() { furi_assert( - furi_hal_subghz_state == SubGhzStateAsyncTx - || furi_hal_subghz_state == SubGhzStateAsyncTxLast - || furi_hal_subghz_state == SubGhzStateAsyncTxEnd - ); + furi_hal_subghz_state == SubGhzStateAsyncTx || + furi_hal_subghz_state == SubGhzStateAsyncTxLast || + furi_hal_subghz_state == SubGhzStateAsyncTxEnd); // Shutdown radio furi_hal_subghz_idle(); diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index c200fc60..7e8c12cd 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -15,166 +15,174 @@ static const uint8_t furi_hal_subghz_preset_ook_270khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION, FIFO Tx=33 Rx=32 /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x67 }, // Rx BW filter is 270.833333kHz + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x67}, // Rx BW filter is 270.833333kHz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_650khz_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x07 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG1, 0x00 }, // Channel spacing is 25kHz - { CC1101_MDMCFG2, 0x30 }, // Format ASK/OOK, No preamble/sync - { CC1101_MDMCFG3, 0x32 }, // Data rate is 3.79372 kBaud - { CC1101_MDMCFG4, 0x17 }, // Rx BW filter is 650.000kHz - + {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz + {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync + {CC1101_MDMCFG3, 0x32}, // Data rate is 3.79372 kBaud + {CC1101_MDMCFG4, 0x17}, // Rx BW filter is 650.000kHz + /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x18}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x11 }, // Adjusts current TX LO buffer + high is PATABLE[1] - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x11}, // Adjusts current TX LO buffer + high is PATABLE[1] + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x88 }, - { CC1101_TEST1, 0x31 }, - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x88}, + {CC1101_TEST1, 0x31}, + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_2fsk_async_regs[][2] = { - // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ - { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input /* FIFO and internals */ - { CC1101_FIFOTHR, 0x47 }, // The only important bit is ADC_RETENTION + {CC1101_FIFOTHR, 0x47}, // The only important bit is ADC_RETENTION /* Packet engine */ - { CC1101_PKTCTRL0, 0x32 }, // Async, continious, no whitening + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening /* Frequency Synthesizer Control */ - { CC1101_FSCTRL1, 0x06 }, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz // Modem Configuration - { CC1101_MDMCFG0, 0xF8 }, - { CC1101_MDMCFG1, 0x00 }, // No preamble/sync - { CC1101_MDMCFG2, 0x80 }, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) - { CC1101_MDMCFG3, 0x83 }, // Data rate is 9.59587 kBaud - { CC1101_MDMCFG4, 0x88 }, // Rx BW filter is 203.125000kHz + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, + {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized) + {CC1101_MDMCFG3, 0x8B}, // Data rate is 19.5885 kBaud + {CC1101_MDMCFG4, 0x69}, // Rx BW filter is 270.833333 kHz - { CC1101_DEVIATN, 0x14}, //Deviation 4.760742 khz + {CC1101_DEVIATN, 0x47}, //Deviation 47.607422 khz /* Main Radio Control State Machine */ - { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) /* Frequency Offset Compensation Configuration */ - { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary - { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET - { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB + {CC1101_AGCTRL0, + 0x40}, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + {CC1101_AGCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCTRL2, 0x03}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ - { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours /* Frontend configuration */ - { CC1101_FREND0, 0x10 }, // Adjusts current TX LO buffer - { CC1101_FREND1, 0xB6 }, // + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0xB6}, // /* Frequency Synthesizer Calibration, valid for 433.92 */ - { CC1101_FSCAL3, 0xE9 }, - { CC1101_FSCAL2, 0x2A }, - { CC1101_FSCAL1, 0x00 }, - { CC1101_FSCAL0, 0x1F }, + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, /* Magic f4ckery */ - { CC1101_TEST2, 0x81 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST1, 0x35 }, // FIFOTHR ADC_RETENTION=1 matched value - { CC1101_TEST0, 0x09 }, // VCO selection calibration stage is disabled + {CC1101_TEST2, 0x81}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST1, 0x35}, // FIFOTHR ADC_RETENTION=1 matched value + {CC1101_TEST0, 0x09}, // VCO selection calibration stage is disabled /* End */ - { 0, 0 }, + {0, 0}, }; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -184,8 +192,7 @@ static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 0x00, @@ -194,8 +201,7 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 -}; + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -217,11 +223,13 @@ void furi_hal_subghz_init() { // GD0 low cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); - while(hal_gpio_read(&gpio_cc1101_g0) != false); + while(hal_gpio_read(&gpio_cc1101_g0) != false) + ; // GD0 high cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(hal_gpio_read(&gpio_cc1101_g0) != true); + while(hal_gpio_read(&gpio_cc1101_g0) != true) + ; // Reset GD0 to floating state cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); @@ -257,8 +265,7 @@ void furi_hal_subghz_dump_state() { printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", cc1101_get_partnumber(device), - cc1101_get_version(device) - ); + cc1101_get_version(device)); furi_hal_spi_device_return(device); } @@ -266,10 +273,10 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { if(preset == FuriHalSubGhzPresetOok650Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_650khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPresetOok270Async){ + } else if(preset == FuriHalSubGhzPresetOok270Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_270khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); - } else if(preset == FuriHalSubGhzPreset2FSKAsync){ + } else if(preset == FuriHalSubGhzPreset2FSKAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); }else { @@ -289,7 +296,7 @@ void furi_hal_subghz_load_registers(const uint8_t data[][2]) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_reset(device); uint32_t i = 0; - while (data[i][0]) { + while(data[i][0]) { cc1101_write_reg(device, data[i][0], data[i][1]); i++; } @@ -401,7 +408,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { while(true) { CC1101Status status = cc1101_get_status(device); - if (status.STATE == CC1101StateIDLE) break; + if(status.STATE == CC1101StateIDLE) break; } furi_hal_spi_device_return(device); @@ -411,16 +418,16 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - if (path == FuriHalSubGhzPath433) { + if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPath315) { + } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - } else if (path == FuriHalSubGhzPath868) { + } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == FuriHalSubGhzPathIsolate) { + } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); } else { @@ -438,24 +445,25 @@ static void furi_hal_subghz_capture_ISR() { if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(true, furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + true, + furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } // Channel 2 if(LL_TIM_IsActiveFlag_CC2(TIM2)) { LL_TIM_ClearFlag_CC2(TIM2); - if (furi_hal_subghz_capture_callback) { - furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context - ); + if(furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback( + false, + LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); } } } - void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); furi_hal_subghz_state = SubGhzStateAsyncRx; @@ -463,12 +471,13 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -498,7 +507,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* // ISR setup furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Interrupts and channels @@ -508,7 +517,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); // Start timer @@ -534,8 +543,8 @@ void furi_hal_subghz_stop_async_rx() { } #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) -#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) -#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2) +#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333 typedef struct { uint32_t* buffer; @@ -547,12 +556,13 @@ typedef struct { static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { - while (samples > 0) { + while(samples > 0) { bool is_odd = samples % 2; - LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); - if (level_duration_is_reset(ld)) { + LevelDuration ld = + furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if(level_duration_is_reset(ld)) { // One more even sample required to end at low level - if (is_odd) { + if(is_odd) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -560,7 +570,7 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { break; } else { // Inject guard time if level is incorrect - if (is_odd == level_duration_get_level(ld)) { + if(is_odd == level_duration_get_level(ld)) { *buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME; buffer++; samples--; @@ -579,21 +589,24 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { static void furi_hal_subghz_async_tx_dma_isr() { furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); - if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } - if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + if(LL_DMA_IsActiveFlag_TC1(DMA1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } } static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { LL_TIM_ClearFlag_UPDATE(TIM2); - if (LL_TIM_GetAutoReload(TIM2) == 0) { - if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + if(LL_TIM_GetAutoReload(TIM2) == 0) { + if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; @@ -612,15 +625,18 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_state = SubGhzStateAsyncTx; - furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); + furi_hal_subghz_async_tx.buffer = + furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill( + furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output - hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + hal_gpio_init_ex( + &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); // Configure DMA LL_DMA_InitTypeDef dma_config = {0}; - dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_CIRCULAR; @@ -632,7 +648,8 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr( + DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -640,7 +657,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* // Configure TIM2 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; - TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 1000; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; @@ -672,7 +689,7 @@ void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_tx(); // Enable NVIC - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); + NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(TIM2_IRQn); LL_TIM_SetCounter(TIM2, 0); @@ -685,10 +702,9 @@ bool furi_hal_subghz_is_async_tx_complete() { void furi_hal_subghz_stop_async_tx() { furi_assert( - furi_hal_subghz_state == SubGhzStateAsyncTx - || furi_hal_subghz_state == SubGhzStateAsyncTxLast - || furi_hal_subghz_state == SubGhzStateAsyncTxEnd - ); + furi_hal_subghz_state == SubGhzStateAsyncTx || + furi_hal_subghz_state == SubGhzStateAsyncTxLast || + furi_hal_subghz_state == SubGhzStateAsyncTxEnd); // Shutdown radio furi_hal_subghz_idle(); diff --git a/lib/subghz/protocols/subghz_protocol.h b/lib/subghz/protocols/subghz_protocol.h deleted file mode 100644 index f4a86c0b..00000000 --- a/lib/subghz/protocols/subghz_protocol.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "subghz_protocol_common.h" - -typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context); -typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context); - -typedef struct SubGhzProtocol SubGhzProtocol; - -/** Allocate SubGhzProtocol - * - * @return SubGhzProtocol* - */ -SubGhzProtocol* subghz_protocol_alloc(); - -/** Free SubGhzProtocol - * - * @param instance - */ -void subghz_protocol_free(SubGhzProtocol* instance); - -/** Get protocol by name - * - * @param instance - SubGhzProtocol instance - * @param name - name protocol - * @param SubGhzProtocolCommon - */ -SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name); - -/** Outputting data text from all parsers - * - * @param instance - SubGhzProtocol instance - * @param callback - SubGhzProtocolTextCallback callback - * @param context - */ -void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context); - -/** Outputting data SubGhzProtocol from all parsers - * - * @param instance - SubGhzProtocol instance - * @param callback - SubGhzProtocolTextCallback callback - * @param context - */ -void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context); - -/** File name rainbow table Nice Flor-S - * - * @param instance - SubGhzProtocol instance - * @param file_name - "path/file_name" - */ -void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name); - -/** File upload manufacture keys - * - * @param instance - SubGhzProtocol instance - * @param file_name - "path/file_name" - */ -void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name); - -/** Restarting all parsers - * - * @param instance - SubGhzProtocol instance - */ -void subghz_protocol_reset(SubGhzProtocol* instance); - -/** Loading data into all parsers - * - * @param instance - SubGhzProtocol instance - * @param level - true is high, false if low - * @param duration - level duration in microseconds - */ -void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration); diff --git a/lib/subghz/protocols/subghz_protocol_came.c b/lib/subghz/protocols/subghz_protocol_came.c index 5d3e5f4c..edace771 100644 --- a/lib/subghz/protocols/subghz_protocol_came.c +++ b/lib/subghz/protocols/subghz_protocol_came.c @@ -11,6 +11,13 @@ struct SubGhzProtocolCame { SubGhzProtocolCommon common; }; +typedef enum { + CameDecoderStepReset = 0, + CameDecoderStepFoundStartBit, + CameDecoderStepSaveDuration, + CameDecoderStepCheckDuration, +} CameDecoderStep; + SubGhzProtocolCame* subghz_protocol_came_alloc() { SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame)); @@ -19,11 +26,11 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() { instance->common.te_short = 320; instance->common.te_long = 640; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_came_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol; @@ -38,97 +45,106 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) { free(instance); } -bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_came_send_key( + SubGhzProtocolCame* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 36); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_came_reset(SubGhzProtocolCame* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_short + switch(instance->common.parser_step) { + case CameDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 51) < + instance->common.te_delta * 51)) { //Need protocol 36 te_short //Found header CAME - instance->common.parser_step = 1; + instance->common.parser_step = CameDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 1: - if (!level) { + case CameDecoderStepFoundStartBit: + if(!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { //Found start bit CAME - instance->common.parser_step = 2; + instance->common.parser_step = CameDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 2: - if (!level) { //save interval - if (duration >= (instance->common.te_short * 4)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - - + case CameDecoderStepSaveDuration: + if(!level) { //save interval + if(duration >= (instance->common.te_short * 4)) { + instance->common.parser_step = CameDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.serial = 0x0; instance->common.btn = 0x0; instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) - instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = CameDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; - case 3: - if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) { + case CameDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = CameDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = CameDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = CameDecoderStepReset; } break; } @@ -150,8 +166,7 @@ void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) instance->common.name, instance->common.code_last_count_bit, code_found_lo, - code_found_reverse_lo - ); + code_found_reverse_lo); } void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) { @@ -165,7 +180,9 @@ void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t out (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance){ +bool subghz_protocol_came_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolCame* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -202,9 +219,7 @@ bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, Su return loaded; } -void subghz_decoder_came_to_load_protocol( - SubGhzProtocolCame* instance, - void* context) { +void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_common.h b/lib/subghz/protocols/subghz_protocol_common.h index 277f89fa..5e7e0633 100644 --- a/lib/subghz/protocols/subghz_protocol_common.h +++ b/lib/subghz/protocols/subghz_protocol_common.h @@ -19,12 +19,11 @@ #define SUBGHZ_APP_EXTENSION ".sub" #define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 512 -enum { - TYPE_PROTOCOL_UNKNOWN, - TYPE_PROTOCOL_STATIC, - TYPE_PROTOCOL_DYNAMIC, -}; - +typedef enum { + SubGhzProtocolCommonTypeUnknown, + SubGhzProtocolCommonTypeStatic, + SubGhzProtocolCommonTypeDynamic, +}SubGhzProtocolCommonType; typedef struct SubGhzProtocolCommon SubGhzProtocolCommon; typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder; @@ -38,7 +37,8 @@ typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output); //Load protocol from file -typedef bool (*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance); +typedef bool ( + *SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance); //Load protocol typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context); //Get upload encoder protocol @@ -56,13 +56,13 @@ struct SubGhzProtocolCommon { uint64_t code_found; uint64_t code_last_found; uint8_t code_min_count_bit_for_found; - uint8_t parser_step; - uint8_t type_protocol; - uint32_t te_last; - uint8_t header_count; - uint16_t cnt; - uint32_t serial; uint8_t btn; + uint8_t header_count; + SubGhzProtocolCommonType type_protocol; + uint32_t te_last; + uint32_t serial; + uint32_t parser_step; + uint16_t cnt; /* Standard Callback for on rx complete event */ SubGhzProtocolCommonCallback callback; @@ -88,7 +88,7 @@ struct SubGhzProtocolCommonEncoder { LevelDuration* upload; }; -struct SubGhzProtocolCommonLoad{ +struct SubGhzProtocolCommonLoad { uint64_t code_found; uint8_t code_count_bit; uint32_t param1; diff --git a/lib/subghz/protocols/subghz_protocol_faac_slh.c b/lib/subghz/protocols/subghz_protocol_faac_slh.c index ee44ec76..8a558be9 100644 --- a/lib/subghz/protocols/subghz_protocol_faac_slh.c +++ b/lib/subghz/protocols/subghz_protocol_faac_slh.c @@ -1,19 +1,25 @@ #include "subghz_protocol_faac_slh.h" - struct SubGhzProtocolFaacSLH { SubGhzProtocolCommon common; }; +typedef enum { + FaacSLHDecoderStepReset = 0, + FaacSLHDecoderStepFoundPreambula, + FaacSLHDecoderStepSaveDuration, + FaacSLHDecoderStepCheckDuration, +} FaacSLHDecoderStep; + SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(void) { SubGhzProtocolFaacSLH* instance = furi_alloc(sizeof(SubGhzProtocolFaacSLH)); - instance->common.name = "Faac SLH"; + instance->common.name = "Faac SLH"; instance->common.code_min_count_bit_for_found = 64; instance->common.te_short = 255; instance->common.te_long = 595; instance->common.te_delta = 100; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_faac_slh_to_load_protocol; @@ -32,7 +38,7 @@ void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) { * @param bit - bit */ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) { - if (bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); @@ -47,22 +53,26 @@ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t } } -void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_protocol_faac_slh_send_key( + SubGhzProtocolFaacSLH* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { SUBGHZ_TX_PIN_HIGH(); //Send header delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long * 2); + delay_us(instance->common.te_long * 2); //Send key data - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1)); } } } void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } /** Analysis of received data @@ -70,7 +80,8 @@ void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) { - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; @@ -79,62 +90,68 @@ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* ins } void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { - instance->common.parser_step = 1; + switch(instance->common.parser_step) { + case FaacSLHDecoderStepReset: + if((level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 3)) { + instance->common.parser_step = FaacSLHDecoderStepFoundPreambula; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 1: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { + case FaacSLHDecoderStepFoundPreambula: + if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 3)) { //Found Preambula - instance->common.parser_step = 2; + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_short * 3 + instance->common.te_delta)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + case FaacSLHDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_short * 3 + instance->common.te_delta)) { + instance->common.parser_step = FaacSLHDecoderStepFoundPreambula; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = FaacSLHDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = FaacSLHDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + case FaacSLHDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = FaacSLHDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = FaacSLHDecoderStepReset; } break; } @@ -142,28 +159,29 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output) { subghz_protocol_faac_slh_check_remote_controller(instance); - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; - uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; + uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF; - string_cat_printf(output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Fix:%08lX \r\n" - "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - (uint32_t)(instance->common.code_last_found >> 32), - (uint32_t)instance->common.code_last_found, - code_fix, code_hop, - instance->common.serial, - instance->common.btn); + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Fix:%08lX \r\n" + "Hop:%08lX \r\n" + "Sn:%07lX Btn:%lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found >> 32), + (uint32_t)instance->common.code_last_found, + code_fix, + code_hop, + instance->common.serial, + instance->common.btn); } -void subghz_decoder_faac_slh_to_load_protocol( - SubGhzProtocolFaacSLH* instance, - void* context) { +void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.c b/lib/subghz/protocols/subghz_protocol_gate_tx.c index 8e10d5f8..3d13b611 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.c +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.c @@ -1,10 +1,16 @@ #include "subghz_protocol_gate_tx.h" - struct SubGhzProtocolGateTX { SubGhzProtocolCommon common; }; +typedef enum { + GateTXDecoderStepReset = 0, + GateTXDecoderStepFoundStartBit, + GateTXDecoderStepSaveDuration, + GateTXDecoderStepCheckDuration, +} GateTXDecoderStep; + SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { SubGhzProtocolGateTX* instance = furi_alloc(sizeof(SubGhzProtocolGateTX)); @@ -13,11 +19,11 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { instance->common.te_short = 350; instance->common.te_long = 700; instance->common.te_delta = 100; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_gate_tx_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol; @@ -31,33 +37,40 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) { free(instance); } -bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_gate_tx_send_key( + SubGhzProtocolGateTX* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 49); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 49); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } /** Analysis of received data @@ -65,68 +78,78 @@ void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) { - uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint32_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - instance->common.serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >>8) & 0xFF) << 4 | ((code_found_reverse >>20) & 0x0F) ; + instance->common.serial = (code_found_reverse & 0xFF) << 12 | + ((code_found_reverse >> 8) & 0xFF) << 4 | + ((code_found_reverse >> 20) & 0x0F); instance->common.btn = ((code_found_reverse >> 16) & 0x0F); } void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_short * 47)< instance->common.te_delta * 47)) { + switch(instance->common.parser_step) { + case GateTXDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 47) < + instance->common.te_delta * 47)) { //Found Preambula - instance->common.parser_step = 1; + instance->common.parser_step = GateTXDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } break; - case 1: - if (level && ((DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3))){ + case GateTXDecoderStepFoundStartBit: + if(level && + ((DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3))) { //Found start bit - instance->common.parser_step = 2; + instance->common.parser_step = GateTXDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } break; - case 2: - if (!level) { - if (duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + case GateTXDecoderStepSaveDuration: + if(!level) { + if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { + instance->common.parser_step = GateTXDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = GateTXDecoderStepCheckDuration; } } - break; - case 3: - if(level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + break; + case GateTXDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < + instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = GateTXDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta * 3) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = GateTXDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = GateTXDecoderStepReset; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = GateTXDecoderStepReset; } break; } @@ -134,16 +157,16 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) { subghz_protocol_gate_tx_check_remote_controller(instance); - string_cat_printf(output, - "%s %dbit\r\n" - "Key:%06lX\r\n" - "Sn:%05lX Btn:%lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - (uint32_t)(instance->common.code_last_found & 0xFFFFFF), - instance->common.serial, - instance->common.btn - ); + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%06lX\r\n" + "Sn:%05lX Btn:%lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0xFFFFFF), + instance->common.serial, + instance->common.btn); } void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) { @@ -157,7 +180,9 @@ void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_ (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance){ +bool subghz_protocol_gate_tx_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolGateTX* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -195,9 +220,7 @@ bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, return loaded; } -void subghz_decoder_gate_tx_to_load_protocol( - SubGhzProtocolGateTX* instance, - void* context) { +void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_ido.c b/lib/subghz/protocols/subghz_protocol_ido.c index a5d33f32..8f7178db 100644 --- a/lib/subghz/protocols/subghz_protocol_ido.c +++ b/lib/subghz/protocols/subghz_protocol_ido.c @@ -4,6 +4,13 @@ struct SubGhzProtocolIDo { SubGhzProtocolCommon common; }; +typedef enum { + IDoDecoderStepReset = 0, + IDoDecoderStepFoundPreambula, + IDoDecoderStepSaveDuration, + IDoDecoderStepCheckDuration, +} IDoDecoderStep; + SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo)); @@ -12,7 +19,7 @@ SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { instance->common.te_short = 450; instance->common.te_long = 1450; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_ido_to_load_protocol; @@ -65,7 +72,7 @@ void subghz_protocol_ido_send_key( } void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } /** Analysis of received data @@ -83,29 +90,29 @@ void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) { void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case IDoDecoderStepReset: if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 5)) { - instance->common.parser_step = 1; + instance->common.parser_step = IDoDecoderStepFoundPreambula; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 1: + case IDoDecoderStepFoundPreambula: if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 5)) { //Found Preambula - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 2: + case IDoDecoderStepSaveDuration: if(level) { if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = IDoDecoderStepFoundPreambula; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; @@ -119,32 +126,32 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = IDoDecoderStepCheckDuration; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; - case 3: + case IDoDecoderStepCheckDuration: if(!level) { if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta * 3) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = IDoDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = IDoDecoderStepReset; } break; } @@ -174,9 +181,7 @@ void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) { instance->common.btn); } -void subghz_decoder_ido_to_load_protocol( - SubGhzProtocolIDo* instance, - void* context) { +void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index ccb2e1ae..e83042d9 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -13,6 +13,13 @@ struct SubGhzProtocolKeeloq { const char* manufacture_name; }; +typedef enum { + KeeloqDecoderStepReset = 0, + KeeloqDecoderStepCheckPreambula, + KeeloqDecoderStepSaveDuration, + KeeloqDecoderStepCheckDuration, +} KeeloqDecoderStep; + SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { SubGhzProtocolKeeloq* instance = furi_alloc(sizeof(SubGhzProtocolKeeloq)); @@ -23,7 +30,7 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { instance->common.te_short = 400; instance->common.te_long = 800; instance->common.te_delta = 140; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str; @@ -297,50 +304,50 @@ bool subghz_protocol_keeloq_send_key( } void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; } void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case KeeloqDecoderStepReset: if((level) && DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { - instance->common.parser_step = 1; + instance->common.parser_step = KeeloqDecoderStepCheckPreambula; instance->common.header_count++; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; } break; - case 1: + case KeeloqDecoderStepCheckPreambula: if((!level) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; break; } if((instance->common.header_count > 2) && (DURATION_DIFF(duration, instance->common.te_short * 10) < instance->common.te_delta * 10)) { // Found header - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } break; - case 2: + case KeeloqDecoderStepSaveDuration: if(level) { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = KeeloqDecoderStepCheckDuration; } break; - case 3: + case KeeloqDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) { // Found end TX - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { if(instance->common.code_last_found != instance->common.code_found) { @@ -363,7 +370,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 1); } - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) && @@ -372,13 +379,13 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 0); } - instance->common.parser_step = 2; + instance->common.parser_step = KeeloqDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = KeeloqDecoderStepReset; instance->common.header_count = 0; } break; diff --git a/lib/subghz/protocols/subghz_protocol_nero_radio.c b/lib/subghz/protocols/subghz_protocol_nero_radio.c index 2a03d722..7e5dd4fe 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_radio.c +++ b/lib/subghz/protocols/subghz_protocol_nero_radio.c @@ -4,6 +4,13 @@ struct SubGhzProtocolNeroRadio { SubGhzProtocolCommon common; }; +typedef enum { + NeroRadioDecoderStepReset = 0, + NeroRadioDecoderStepCheckPreambula, + NeroRadioDecoderStepSaveDuration, + NeroRadioDecoderStepCheckDuration, +} NeroRadioDecoderStep; + SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) { SubGhzProtocolNeroRadio* instance = furi_alloc(sizeof(SubGhzProtocolNeroRadio)); @@ -12,7 +19,7 @@ SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) { instance->common.te_short = 200; instance->common.te_long = 400; instance->common.te_delta = 80; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_radio_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_radio_to_save_str; @@ -74,7 +81,7 @@ bool subghz_protocol_nero_radio_send_key( } void subghz_protocol_nero_radio_reset(SubGhzProtocolNeroRadio* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } /** Analysis of received data @@ -99,24 +106,24 @@ void subghz_protocol_nero_radio_parse( bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case NeroRadioDecoderStepReset: if((level) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = NeroRadioDecoderStepCheckPreambula; instance->common.te_last = duration; instance->common.header_count = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 1: + case NeroRadioDecoderStepCheckPreambula: if(level) { if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) || (DURATION_DIFF(duration, instance->common.te_short * 4) < instance->common.te_delta)) { instance->common.te_last = duration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) < @@ -129,32 +136,32 @@ void subghz_protocol_nero_radio_parse( instance->common.te_delta) { // Found start bit if(instance->common.header_count > 40) { - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 2: + case NeroRadioDecoderStepSaveDuration: if(level) { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NeroRadioDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; - case 3: + case NeroRadioDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 10 + instance->common.te_delta * 2)) { //Found stop bit - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; if(instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; @@ -165,25 +172,25 @@ void subghz_protocol_nero_radio_parse( } instance->common.code_found = 0; instance->common.code_count_bit = 0; - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; break; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NeroRadioDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroRadioDecoderStepReset; } break; } diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.c b/lib/subghz/protocols/subghz_protocol_nero_sketch.c index 4663bc05..bbb487c8 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.c +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.c @@ -1,23 +1,29 @@ #include "subghz_protocol_nero_sketch.h" - struct SubGhzProtocolNeroSketch { SubGhzProtocolCommon common; }; +typedef enum { + NeroSketchDecoderStepReset = 0, + NeroSketchDecoderStepCheckPreambula, + NeroSketchDecoderStepSaveDuration, + NeroSketchDecoderStepCheckDuration, +} NeroSketchDecoderStep; + SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { SubGhzProtocolNeroSketch* instance = furi_alloc(sizeof(SubGhzProtocolNeroSketch)); - instance->common.name = "Nero Sketch"; + instance->common.name = "Nero Sketch"; instance->common.code_min_count_bit_for_found = 40; instance->common.te_short = 330; instance->common.te_long = 660; instance->common.te_delta = 150; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol; @@ -32,45 +38,51 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) { free(instance); } -bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_nero_sketch_send_key( + SubGhzProtocolNeroSketch* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload = 47*2+2+(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = 47 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; - + //Send header - for(uint8_t i = 0; i < 47; i++){ + for(uint8_t i = 0; i < 47; i++) { encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); } - + //Send start bit - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*4); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 4); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); } } //Send stop bit - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*3); + encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 3); encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); return true; } void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } /** Analysis of received data @@ -90,112 +102,123 @@ void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { // } -void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((level) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { - instance->common.parser_step = 1; +void subghz_protocol_nero_sketch_parse( + SubGhzProtocolNeroSketch* instance, + bool level, + uint32_t duration) { + switch(instance->common.parser_step) { + case NeroSketchDecoderStepReset: + if((level) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { + instance->common.parser_step = NeroSketchDecoderStepCheckPreambula; instance->common.te_last = duration; instance->common.header_count = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 1: - if (level){ - if((DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta ) - || (DURATION_DIFF(duration,instance->common.te_short*4)< instance->common.te_delta)) { + case NeroSketchDecoderStepCheckPreambula: + if(level) { + if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) || + (DURATION_DIFF(duration, instance->common.te_short * 4) < + instance->common.te_delta)) { instance->common.te_last = duration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } - } else if(DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta){ - if(DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta){ + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { + if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) { // Found header instance->common.header_count++; break; - }else if(DURATION_DIFF(instance->common.te_last,instance->common.te_short*4)< instance->common.te_delta){ - // Found start bit - if(instance->common.header_count>40) { - instance->common.parser_step = 2; + } else if( + DURATION_DIFF(instance->common.te_last, instance->common.te_short * 4) < + instance->common.te_delta) { + // Found start bit + if(instance->common.header_count > 40) { + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; - }else { - instance->common.parser_step = 0; - } + } else { + instance->common.parser_step = NeroSketchDecoderStepReset; + } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_short * 2 + instance->common.te_delta*2)) { + case NeroSketchDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_short * 2 + instance->common.te_delta * 2)) { //Found stop bit - instance->common.parser_step = 0; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + instance->common.parser_step = NeroSketchDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NeroSketchDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = NeroSketchDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + case NeroSketchDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NeroSketchDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = NeroSketchDecoderStepReset; } break; } } void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse>>32; - uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf(output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Yek:0x%lX%08lX\r\n", - instance->common.name, - instance->common.code_last_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - code_found_reverse_lo - ); + string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Yek:0x%lX%08lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + code_found_hi, + code_found_lo, + code_found_reverse_hi, + code_found_reverse_lo); } void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) { @@ -210,11 +233,12 @@ void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, instance->common.name, instance->common.code_last_count_bit, code_found_hi, - code_found_lo - ); + code_found_lo); } -bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){ +bool subghz_protocol_nero_sketch_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolNeroSketch* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -242,7 +266,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor if(res != 2) { break; } - instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo; + instance->common.code_last_found = (uint64_t)temp_key_hi << 32 | temp_key_lo; loaded = true; } while(0); @@ -252,9 +276,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor return loaded; } -void subghz_decoder_nero_sketch_to_load_protocol( - SubGhzProtocolNeroSketch* instance, - void* context) { +void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_nice_flo.c b/lib/subghz/protocols/subghz_protocol_nice_flo.c index af778543..640eea25 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flo.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flo.c @@ -10,6 +10,13 @@ struct SubGhzProtocolNiceFlo { SubGhzProtocolCommon common; }; +typedef enum { + NiceFloDecoderStepReset = 0, + NiceFloDecoderStepFoundStartBit, + NiceFloDecoderStepSaveDuration, + NiceFloDecoderStepCheckDuration, +} NiceFloDecoderStep; + SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { SubGhzProtocolNiceFlo* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlo)); @@ -18,11 +25,11 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() { instance->common.te_short = 700; instance->common.te_long = 1400; instance->common.te_delta = 200; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flo_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_protocol_nice_flo_to_save_str; - instance->common.to_load_protocol_from_file= + instance->common.to_load_protocol_from_file = (SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol; @@ -36,94 +43,105 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) { free(instance); } -bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder){ +bool subghz_protocol_nice_flo_send_key( + SubGhzProtocolNiceFlo* instance, + SubGhzProtocolCommonEncoder* encoder) { furi_assert(instance); furi_assert(encoder); size_t index = 0; - encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2; + encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2; if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false; //Send header - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short * 36); //Send start bit encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); //Send key data - for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { - if(bit_read(instance->common.code_last_found, i - 1)){ + for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) { + if(bit_read(instance->common.code_last_found, i - 1)) { //send bit 1 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short); - }else{ + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_short); + } else { //send bit 0 - encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short); - encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long); + encoder->upload[index++] = + level_duration_make(false, (uint32_t)instance->common.te_short); + encoder->upload[index++] = + level_duration_make(true, (uint32_t)instance->common.te_long); } } return true; } void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if ((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 36)< instance->common.te_delta * 36)) { + switch(instance->common.parser_step) { + case NiceFloDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) < + instance->common.te_delta * 36)) { //Found header Nice Flo - instance->common.parser_step = 1; + instance->common.parser_step = NiceFloDecoderStepFoundStartBit; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 1: - if (!level) { + case NiceFloDecoderStepFoundStartBit: + if(!level) { break; - } else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) { + } else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) { //Found start bit Nice Flo - instance->common.parser_step = 2; + instance->common.parser_step = NiceFloDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 2: - if (!level) { //save interval - if (duration >= (instance->common.te_short * 4)) { - instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - + case NiceFloDecoderStepSaveDuration: + if(!level) { //save interval + if(duration >= (instance->common.te_short * 4)) { + instance->common.parser_step = NiceFloDecoderStepFoundStartBit; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.serial = 0x0; instance->common.btn = 0x0; instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = NiceFloDecoderStepCheckDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; - case 3: - if (level) { - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) { + case NiceFloDecoderStepCheckDuration: + if(level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) { + instance->common.parser_step = NiceFloDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = NiceFloDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFloDecoderStepReset; } break; } @@ -145,11 +163,9 @@ void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t o instance->common.name, instance->common.code_last_count_bit, code_found_lo, - code_found_reverse_lo - ); + code_found_reverse_lo); } - void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) { string_printf( output, @@ -161,7 +177,9 @@ void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, strin (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); } -bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){ +bool subghz_protocol_nice_flo_to_load_protocol_from_file( + FileWorker* file_worker, + SubGhzProtocolNiceFlo* instance) { bool loaded = false; string_t temp_str; string_init(temp_str); @@ -198,9 +216,7 @@ bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker return loaded; } -void subghz_decoder_nice_flo_to_load_protocol( - SubGhzProtocolNiceFlo* instance, - void* context) { +void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c index 84b81334..41da7373 100644 --- a/lib/subghz/protocols/subghz_protocol_nice_flor_s.c +++ b/lib/subghz/protocols/subghz_protocol_nice_flor_s.c @@ -13,6 +13,14 @@ struct SubGhzProtocolNiceFlorS { const char* rainbow_table_file_name; }; +typedef enum { + NiceFlorSDecoderStepReset = 0, + NiceFlorSDecoderStepCheckHeader, + NiceFlorSDecoderStepFoundHeader, + NiceFlorSDecoderStepSaveDuration, + NiceFlorSDecoderStepCheckDuration, +} NiceFlorSDecoderStep; + SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { SubGhzProtocolNiceFlorS* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlorS)); @@ -21,7 +29,7 @@ SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() { instance->common.te_short = 500; instance->common.te_long = 1000; instance->common.te_delta = 300; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flor_s_to_load_protocol; @@ -93,16 +101,14 @@ void subghz_protocol_nice_flor_s_send_key( * @return byte data */ uint8_t subghz_nice_flor_s_get_byte_in_file(SubGhzProtocolNiceFlorS* instance, uint32_t address) { - if(!instance->rainbow_table_file_name) - return 0; + if(!instance->rainbow_table_file_name) return 0; uint8_t buffer = 0; FileWorker* file_worker = file_worker_alloc(true); - if(file_worker_open(file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) { + if(file_worker_open( + file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) { file_worker_seek(file_worker, address, true); file_worker_read(file_worker, &buffer, 1); - // bool res = file_worker_read(file_worker, &buffer, 1); - // furi_assert(res== true); } file_worker_close(file_worker); file_worker_free(file_worker); @@ -134,8 +140,11 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) { */ uint16_t p3p4 = (uint16_t)(instance->common.code_last_found >> 24); - instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1); - uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff))); + instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance, p3p4 * 2) << 8 | + subghz_nice_flor_s_get_byte_in_file(instance, p3p4 * 2 + 1); + uint8_t k = + (uint8_t)(p3p4 & 0x00FF) ^ + subghz_nice_flor_s_get_byte_in_file(instance, (0x20000 | (instance->common.cnt & 0x00ff))); uint8_t s3 = ((uint8_t)(instance->common.code_last_found >> 40) ^ k) & 0x0f; uint8_t s2 = ((uint8_t)(instance->common.code_last_found >> 16) ^ k); @@ -147,73 +156,82 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) { } void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } -void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration) { +void subghz_protocol_nice_flor_s_parse( + SubGhzProtocolNiceFlorS* instance, + bool level, + uint32_t duration) { switch(instance->common.parser_step) { - case 0: - if((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 38) < instance->common.te_delta * 38)) { + case NiceFlorSDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 38) < + instance->common.te_delta * 38)) { //Found start header Nice Flor-S - instance->common.parser_step = 1; + instance->common.parser_step = NiceFlorSDecoderStepCheckHeader; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 1: - if((level) - && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { + case NiceFlorSDecoderStepCheckHeader: + if((level) && (DURATION_DIFF(duration, instance->common.te_short * 3) < + instance->common.te_delta * 3)) { //Found next header Nice Flor-S - instance->common.parser_step = 2; + instance->common.parser_step = NiceFlorSDecoderStepFoundHeader; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 2: - if((!level) - && (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) { + case NiceFlorSDecoderStepFoundHeader: + if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 3) < + instance->common.te_delta * 3)) { //Found header Nice Flor-S - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; - case 3: + case NiceFlorSDecoderStepSaveDuration: if(level) { - if(DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta) { + if(DURATION_DIFF(duration, instance->common.te_short * 3) < + instance->common.te_delta) { //Found STOP bit - instance->common.parser_step = 0; - if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) { + instance->common.parser_step = NiceFlorSDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } break; } else { //save interval instance->common.te_last = duration; - instance->common.parser_step = 4; + instance->common.parser_step = NiceFlorSDecoderStepCheckDuration; } } break; - case 4: + case NiceFlorSDecoderStepCheckDuration: if(!level) { - if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta) - &&(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; } else if( - (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) - &&(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 3; + instance->common.parser_step = NiceFlorSDecoderStepSaveDuration; } else - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } else { - instance->common.parser_step = 0; + instance->common.parser_step = NiceFlorSDecoderStepReset; } break; } @@ -236,13 +254,10 @@ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, strin code_found_lo, instance->common.serial, instance->common.cnt, - instance->common.btn - ); + instance->common.btn); } -void subghz_decoder_nice_flor_s_to_load_protocol( - SubGhzProtocolNiceFlorS* instance, - void* context) { +void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_princeton.c b/lib/subghz/protocols/subghz_protocol_princeton.c index 0cd60387..700d221f 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.c +++ b/lib/subghz/protocols/subghz_protocol_princeton.c @@ -16,6 +16,12 @@ struct SubGhzEncoderPrinceton { size_t front; }; +typedef enum { + PrincetonDecoderStepReset = 0, + PrincetonDecoderStepSaveDuration, + PrincetonDecoderStepCheckDuration, +} PrincetonDecoderStep; + SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() { SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton)); return instance; @@ -87,7 +93,7 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) { instance->common.te_short = SUBGHZ_PT_SHORT; //150; instance->common.te_long = SUBGHZ_PT_LONG; //450; instance->common.te_delta = 250; //50; - instance->common.type_protocol = TYPE_PROTOCOL_STATIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str; instance->common.to_save_string = (SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str; @@ -142,7 +148,7 @@ bool subghz_protocol_princeton_send_key( } void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } void subghz_decoder_princeton_parse( @@ -150,28 +156,28 @@ void subghz_decoder_princeton_parse( bool level, uint32_t duration) { switch(instance->common.parser_step) { - case 0: + case PrincetonDecoderStepReset: if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) < instance->common.te_delta * 36)) { //Found Preambula - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; instance->common.code_found = 0; instance->common.code_count_bit = 0; } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } break; - case 1: + case PrincetonDecoderStepSaveDuration: //save duration if(level) { instance->common.te_last = duration; - instance->common.parser_step = 2; + instance->common.parser_step = PrincetonDecoderStepCheckDuration; } break; - case 2: + case PrincetonDecoderStepCheckDuration: if(!level) { if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) { - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; if(instance->common.code_count_bit == instance->common.code_min_count_bit_for_found) { if(instance->common.code_last_found == instance->common.code_found) { @@ -201,18 +207,18 @@ void subghz_decoder_princeton_parse( (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; } else if( (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta * 3) && (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 1; + instance->common.parser_step = PrincetonDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = PrincetonDecoderStepReset; } break; } @@ -306,9 +312,7 @@ bool subghz_decoder_princeton_to_load_protocol_from_file( return loaded; } -void subghz_decoder_princeton_to_load_protocol( - SubGhzDecoderPrinceton* instance, - void* context) { +void subghz_decoder_princeton_to_load_protocol(SubGhzDecoderPrinceton* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol_star_line.c b/lib/subghz/protocols/subghz_protocol_star_line.c index 001285f3..3aae6087 100644 --- a/lib/subghz/protocols/subghz_protocol_star_line.c +++ b/lib/subghz/protocols/subghz_protocol_star_line.c @@ -8,24 +8,30 @@ #include #include - struct SubGhzProtocolStarLine { SubGhzProtocolCommon common; SubGhzKeystore* keystore; const char* manufacture_name; }; +typedef enum { + StarLineDecoderStepReset = 0, + StarLineDecoderStepCheckPreambula, + StarLineDecoderStepSaveDuration, + StarLineDecoderStepCheckDuration, +} StarLineDecoderStep; + SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore) { SubGhzProtocolStarLine* instance = furi_alloc(sizeof(SubGhzProtocolStarLine)); instance->keystore = keystore; - instance->common.name = "Star Line"; + instance->common.name = "Star Line"; instance->common.code_min_count_bit_for_found = 64; instance->common.te_short = 250; instance->common.te_long = 500; instance->common.te_delta = 120; - instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_star_line_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_star_line_to_load_protocol; @@ -38,13 +44,13 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) { free(instance); } -const char* subghz_protocol_star_line_find_and_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){ +const char* subghz_protocol_star_line_get_manufacture_name(void* context) { SubGhzProtocolStarLine* instance = context; return instance->manufacture_name; } @@ -55,7 +61,7 @@ const char* subghz_protocol_star_line_get_manufacture_name (void* context){ * @param bit - bit */ void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) { - if (bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long); @@ -70,18 +76,22 @@ void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_ } } -void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_protocol_star_line_send_key( + SubGhzProtocolStarLine* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { //Send header - for(uint8_t i = 0; i < 6; i++){ + for(uint8_t i = 0; i < 6; i++) { SUBGHZ_TX_PIN_HIGH(); delay_us(instance->common.te_long * 2); SUBGHZ_TX_PIN_LOW(); - delay_us(instance->common.te_long * 2); - } + delay_us(instance->common.te_long * 2); + } //Send Start bit ?????????? //Send key data - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_star_line_send_bit(instance, bit_read(key, i - 1)); } //Send Stop bit ?????????? @@ -89,7 +99,7 @@ void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64 } void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } /** Checking the accepted code against the database manafacture key @@ -99,86 +109,97 @@ void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) { * @param hop hop encrypted part of the parcel * @return true on successful search */ -uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtocolStarLine* instance, uint32_t fix , uint32_t hop) { - uint16_t end_serial = (uint16_t)(fix&0xFF); - uint8_t btn = (uint8_t)(fix>>24); +uint8_t subghz_protocol_star_line_check_remote_controller_selector( + SubGhzProtocolStarLine* instance, + uint32_t fix, + uint32_t hop) { + uint16_t end_serial = (uint16_t)(fix & 0xFF); + uint8_t btn = (uint8_t)(fix >> 24); uint32_t decrypt = 0; uint64_t man_normal_learning; for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - switch (manufacture_code->type){ - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if((decrypt>>24 == btn) && ((((uint16_t)(decrypt>>16)) & 0x00FF) == end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + switch(manufacture_code->type) { + case KEELOQ_LEARNING_SIMPLE: + //Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_NORMAL: - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_NORMAL: + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt=subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } - // Check for mirrored man - uint64_t man_rev=0; - uint64_t man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte=(uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - //########################### - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - // Check for mirrored man - man_rev=0; - man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_UNKNOWN: + // Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + uint64_t man_rev = 0; + uint64_t man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + //########################### + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + man_rev = 0; + man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 24 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; } } instance->manufacture_name = "Unknown"; - instance->common.cnt=0; + instance->common.cnt = 0; return 0; } @@ -188,53 +209,61 @@ uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtoco * @param instance SubGhzProtocolStarLine instance */ void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance) { - uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t key = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; subghz_protocol_star_line_check_remote_controller_selector(instance, key_fix, key_hop); - instance ->common.serial= key_fix&0x00FFFFFF; + instance->common.serial = key_fix & 0x00FFFFFF; instance->common.btn = key_fix >> 24; } -void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { - case 0: - if (level){ - if(DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2) { - instance->common.parser_step = 1; +void subghz_protocol_star_line_parse( + SubGhzProtocolStarLine* instance, + bool level, + uint32_t duration) { + switch(instance->common.parser_step) { + case StarLineDecoderStepReset: + if(level) { + if(DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 2) { + instance->common.parser_step = StarLineDecoderStepCheckPreambula; instance->common.header_count++; - } else if(instance->common.header_count>4){ + } else if(instance->common.header_count > 4) { instance->common.code_found = 0; instance->common.code_count_bit = 0; instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = StarLineDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = StarLineDecoderStepReset; instance->common.header_count = 0; } break; - case 1: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2)) { + case StarLineDecoderStepCheckPreambula: + if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) < + instance->common.te_delta * 2)) { //Found Preambula - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } else { instance->common.header_count = 0; - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } break; - case 2: - if (level) { - if (duration >= (instance->common.te_long + instance->common.te_delta)) { - instance->common.parser_step = 0; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - if(instance->common.code_last_found != instance->common.code_found){ + case StarLineDecoderStepSaveDuration: + if(level) { + if(duration >= (instance->common.te_long + instance->common.te_delta)) { + instance->common.parser_step = StarLineDecoderStepReset; + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { + if(instance->common.code_last_found != instance->common.code_found) { instance->common.code_last_found = instance->common.code_found; instance->common.code_last_count_bit = instance->common.code_count_bit; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } } instance->common.code_found = 0; @@ -243,28 +272,31 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve break; } else { instance->common.te_last = duration; - instance->common.parser_step = 3; + instance->common.parser_step = StarLineDecoderStepCheckDuration; } - }else{ - instance->common.parser_step = 0; + } else { + instance->common.parser_step = StarLineDecoderStepReset; } break; - case 3: - if(!level){ - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) { + case StarLineDecoderStepCheckDuration: + if(!level) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 0); - instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) { + instance->common.parser_step = StarLineDecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); - instance->common.parser_step = 2; + instance->common.parser_step = StarLineDecoderStepSaveDuration; } else { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } } else { - instance->common.parser_step = 0; + instance->common.parser_step = StarLineDecoderStepReset; } break; } @@ -275,10 +307,11 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t uint32_t code_found_hi = instance->common.code_last_found >> 32; uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse>>32; - uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; string_cat_printf( output, "%s %dbit\r\n" @@ -296,13 +329,10 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t code_found_reverse_lo, instance->common.btn, instance->manufacture_name, - instance->common.serial - ); + instance->common.serial); } -void subghz_decoder_star_line_to_load_protocol( - SubGhzProtocolStarLine* instance, - void* context) { +void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context) { furi_assert(context); furi_assert(instance); SubGhzProtocolCommonLoad* data = context; diff --git a/lib/subghz/protocols/subghz_protocol.c b/lib/subghz/subghz_parser.c similarity index 82% rename from lib/subghz/protocols/subghz_protocol.c rename to lib/subghz/subghz_parser.c index 616139a2..6fc8f1f4 100644 --- a/lib/subghz/protocols/subghz_protocol.c +++ b/lib/subghz/subghz_parser.c @@ -1,18 +1,19 @@ -#include "subghz_protocol.h" -#include "subghz_protocol_came.h" -#include "subghz_protocol_cfm.h" -#include "subghz_protocol_keeloq.h" -#include "subghz_protocol_nice_flo.h" -#include "subghz_protocol_nice_flor_s.h" -#include "subghz_protocol_princeton.h" -#include "subghz_protocol_gate_tx.h" -#include "subghz_protocol_ido.h" -#include "subghz_protocol_faac_slh.h" -#include "subghz_protocol_nero_sketch.h" -#include "subghz_protocol_star_line.h" -#include "subghz_protocol_nero_radio.h" -#include "../subghz_keystore.h" +#include "subghz_parser.h" +#include "protocols/subghz_protocol_came.h" +#include "protocols/subghz_protocol_cfm.h" +#include "protocols/subghz_protocol_keeloq.h" +#include "protocols/subghz_protocol_nice_flo.h" +#include "protocols/subghz_protocol_nice_flor_s.h" +#include "protocols/subghz_protocol_princeton.h" +#include "protocols/subghz_protocol_gate_tx.h" +#include "protocols/subghz_protocol_ido.h" +#include "protocols/subghz_protocol_faac_slh.h" +#include "protocols/subghz_protocol_nero_sketch.h" +#include "protocols/subghz_protocol_star_line.h" +#include "protocols/subghz_protocol_nero_radio.h" + +#include "subghz_keystore.h" #include #include @@ -33,7 +34,7 @@ typedef enum { SubGhzProtocolTypeMax, } SubGhzProtocolType; -struct SubGhzProtocol { +struct SubGhzParser { SubGhzKeystore* keystore; SubGhzProtocolCommon* protocols[SubGhzProtocolTypeMax]; @@ -44,8 +45,8 @@ struct SubGhzProtocol { void* parser_callback_context; }; -static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* context) { - SubGhzProtocol* instance = context; +static void subghz_parser_text_rx_callback(SubGhzProtocolCommon* parser, void* context) { + SubGhzParser* instance = context; string_t output; string_init(output); @@ -58,15 +59,15 @@ static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* string_clear(output); } -static void subghz_protocol_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) { - SubGhzProtocol* instance = context; +static void subghz_parser_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) { + SubGhzParser* instance = context; if(instance->parser_callback) { instance->parser_callback(parser, instance->parser_callback_context); } } -SubGhzProtocol* subghz_protocol_alloc() { - SubGhzProtocol* instance = furi_alloc(sizeof(SubGhzProtocol)); +SubGhzParser* subghz_parser_alloc() { + SubGhzParser* instance = furi_alloc(sizeof(SubGhzParser)); instance->keystore = subghz_keystore_alloc(); @@ -96,7 +97,7 @@ SubGhzProtocol* subghz_protocol_alloc() { return instance; } -void subghz_protocol_free(SubGhzProtocol* instance) { +void subghz_parser_free(SubGhzParser* instance) { furi_assert(instance); subghz_protocol_came_free((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); @@ -125,7 +126,7 @@ void subghz_protocol_free(SubGhzProtocol* instance) { free(instance); } -SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name) { +SubGhzProtocolCommon* subghz_parser_get_by_name(SubGhzParser* instance, const char* name) { SubGhzProtocolCommon* result = NULL; for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { @@ -138,46 +139,46 @@ SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, cons return result; } -void subghz_protocol_enable_dump_text( - SubGhzProtocol* instance, +void subghz_parser_enable_dump_text( + SubGhzParser* instance, SubGhzProtocolTextCallback callback, void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { subghz_protocol_common_set_callback( - instance->protocols[i], subghz_protocol_text_rx_callback, instance); + instance->protocols[i], subghz_parser_text_rx_callback, instance); } instance->text_callback = callback; instance->text_callback_context = context; } -void subghz_protocol_enable_dump( - SubGhzProtocol* instance, +void subghz_parser_enable_dump( + SubGhzParser* instance, SubGhzProtocolCommonCallbackDump callback, void* context) { furi_assert(instance); for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { subghz_protocol_common_set_callback( - instance->protocols[i], subghz_protocol_parser_rx_callback, instance); + instance->protocols[i], subghz_parser_parser_rx_callback, instance); } instance->parser_callback = callback; instance->parser_callback_context = context; } -void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) { +void subghz_parser_load_nice_flor_s_file(SubGhzParser* instance, const char* file_name) { subghz_protocol_nice_flor_s_name_file( (SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name); } -void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) { +void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name) { subghz_keystore_load(instance->keystore, file_name); } -void subghz_protocol_reset(SubGhzProtocol* instance) { +void subghz_parser_reset(SubGhzParser* instance) { subghz_protocol_came_reset((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); subghz_protocol_keeloq_reset( (SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); @@ -200,7 +201,7 @@ void subghz_protocol_reset(SubGhzProtocol* instance) { (SubGhzProtocolNeroRadio*)instance->protocols[SubGhzProtocolTypeNeroRadio]); } -void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) { +void subghz_parser_parse(SubGhzParser* instance, bool level, uint32_t duration) { subghz_protocol_came_parse( (SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration); subghz_protocol_keeloq_parse( diff --git a/lib/subghz/subghz_parser.h b/lib/subghz/subghz_parser.h new file mode 100644 index 00000000..69341c18 --- /dev/null +++ b/lib/subghz/subghz_parser.h @@ -0,0 +1,72 @@ +#pragma once + +#include "protocols/subghz_protocol_common.h" + +typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context); +typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context); + +typedef struct SubGhzParser SubGhzParser; + +/** Allocate SubGhzParser + * + * @return SubGhzParser* + */ +SubGhzParser* subghz_parser_alloc(); + +/** Free SubGhzParser + * + * @param instance + */ +void subghz_parser_free(SubGhzParser* instance); + +/** Get protocol by name + * + * @param instance - SubGhzParser instance + * @param name - name protocol + * @param SubGhzProtocolCommon + */ +SubGhzProtocolCommon* subghz_parser_get_by_name(SubGhzParser* instance, const char* name); + +/** Outputting data text from all parsers + * + * @param instance - SubGhzParser instance + * @param callback - SubGhzProtocolTextCallback callback + * @param context + */ +void subghz_parser_enable_dump_text(SubGhzParser* instance, SubGhzProtocolTextCallback callback, void* context); + +/** Outputting data SubGhzParser from all parsers + * + * @param instance - SubGhzParser instance + * @param callback - SubGhzProtocolTextCallback callback + * @param context + */ +void subghz_parser_enable_dump(SubGhzParser* instance, SubGhzProtocolCommonCallbackDump callback, void* context); + +/** File name rainbow table Nice Flor-S + * + * @param instance - SubGhzParser instance + * @param file_name - "path/file_name" + */ +void subghz_parser_load_nice_flor_s_file(SubGhzParser* instance, const char* file_name); + +/** File upload manufacture keys + * + * @param instance - SubGhzParser instance + * @param file_name - "path/file_name" + */ +void subghz_parser_load_keeloq_file(SubGhzParser* instance, const char* file_name); + +/** Restarting all parsers + * + * @param instance - SubGhzParser instance + */ +void subghz_parser_reset(SubGhzParser* instance); + +/** Loading data into all parsers + * + * @param instance - SubGhzParser instance + * @param level - true is high, false if low + * @param duration - level duration in microseconds + */ +void subghz_parser_parse(SubGhzParser* instance, bool level, uint32_t duration);