From 9d1b14effa6d8673ed39cd7a2ee3167b7fde1a10 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 12 Feb 2024 13:32:27 +0000 Subject: [PATCH 1/8] furi hal gpio: allow enabling interrupt without handler --- targets/f7/furi_hal/furi_hal_gpio.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/targets/f7/furi_hal/furi_hal_gpio.c b/targets/f7/furi_hal/furi_hal_gpio.c index 1e703b5d1..da195bdca 100644 --- a/targets/f7/furi_hal/furi_hal_gpio.c +++ b/targets/f7/furi_hal/furi_hal_gpio.c @@ -215,11 +215,8 @@ void furi_hal_gpio_enable_int_callback(const GpioPin* gpio) { FURI_CRITICAL_ENTER(); - uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); - if(gpio_interrupt[pin_num].callback) { - const uint32_t exti_line = GET_EXTI_LINE(gpio->pin); - LL_EXTI_EnableIT_0_31(exti_line); - } + const uint32_t exti_line = GET_EXTI_LINE(gpio->pin); + LL_EXTI_EnableIT_0_31(exti_line); FURI_CRITICAL_EXIT(); } From 0fddc8ed6090362888f6b1090f3aac38e2abae60 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 12 Feb 2024 13:33:33 +0000 Subject: [PATCH 2/8] signal reader: explicitly enable and disable gpio interrupt --- lib/signal_reader/signal_reader.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/signal_reader/signal_reader.c b/lib/signal_reader/signal_reader.c index 1c08d29f4..c06c7a5c0 100644 --- a/lib/signal_reader/signal_reader.c +++ b/lib/signal_reader/signal_reader.c @@ -228,6 +228,7 @@ void signal_reader_start(SignalReader* instance, SignalReaderCallback callback, /* We need the EXTI to be configured as interrupt generating line, but no ISR registered */ furi_hal_gpio_init( instance->pin, GpioModeInterruptRiseFall, instance->pull, GpioSpeedVeryHigh); + furi_hal_gpio_enable_int_callback(instance->pin); /* Set DMAMUX request generation signal ID on specified DMAMUX channel */ LL_DMAMUX_SetRequestSignalID( @@ -309,6 +310,8 @@ void signal_reader_stop(SignalReader* instance) { furi_hal_interrupt_set_isr(SIGNAL_READER_DMA_GPIO_IRQ, NULL, NULL); + furi_hal_gpio_disable_int_callback(instance->pin); + // Deinit DMA Rx pin LL_DMA_DeInit(SIGNAL_READER_DMA_GPIO_DEF); // Deinit DMA Sync timer From d61931e69deb3293a9b7d05f70d542ad78f3e0c6 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:26:12 +0300 Subject: [PATCH 3/8] run fbtformat --- .../main/nfc/plugins/supported_cards/social_moscow.c | 2 +- applications/main/nfc/plugins/supported_cards/troika.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/main/nfc/plugins/supported_cards/social_moscow.c b/applications/main/nfc/plugins/supported_cards/social_moscow.c index 321526320..714b4eb95 100644 --- a/applications/main/nfc/plugins/supported_cards/social_moscow.c +++ b/applications/main/nfc/plugins/supported_cards/social_moscow.c @@ -671,7 +671,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date)*24 * 60 + card_start_trip_time, + (card_start_trip_date) * 24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( diff --git a/applications/main/nfc/plugins/supported_cards/troika.c b/applications/main/nfc/plugins/supported_cards/troika.c index 22e262241..c3f765961 100644 --- a/applications/main/nfc/plugins/supported_cards/troika.c +++ b/applications/main/nfc/plugins/supported_cards/troika.c @@ -620,7 +620,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date)*24 * 60 + card_start_trip_time, + (card_start_trip_date) * 24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -697,7 +697,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date)*24 * 60 + card_start_trip_time, + (card_start_trip_date) * 24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -871,7 +871,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { from_days_to_datetime(card_use_before_date, &card_use_before_date_s, 1992); FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date)*24 * 60 + card_start_trip_time, + (card_start_trip_date) * 24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -952,7 +952,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { from_days_to_datetime(card_use_before_date, &card_use_before_date_s, 1992); FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_start_trip_date)*24 * 60 + card_start_trip_time, + (card_start_trip_date) * 24 * 60 + card_start_trip_time, &card_start_trip_minutes_s, 1992); furi_string_printf( @@ -1092,7 +1092,7 @@ bool parse_transport_block(const MfClassicBlock* block, FuriString* result) { FuriHalRtcDateTime card_start_trip_minutes_s = {0}; from_minutes_to_datetime( - (card_valid_to_date)*24 * 60 + card_valid_for_minutes - card_start_trip_neg_minutes, + (card_valid_to_date) * 24 * 60 + card_valid_for_minutes - card_start_trip_neg_minutes, &card_start_trip_minutes_s, 2016); //-time furi_string_printf( From 0f7411d03a374d15964e77c79bccfc3525f1cd81 Mon Sep 17 00:00:00 2001 From: nminaylov Date: Mon, 12 Feb 2024 18:06:01 +0300 Subject: [PATCH 4/8] JS serial module renamed, uart channel selection --- applications/system/js_app/application.fam | 6 +- .../js_app/examples/apps/Scripts/bad_uart.js | 22 +- .../js_app/examples/apps/Scripts/uart_echo.js | 8 +- .../js_app/modules/{js_uart.c => js_serial.c} | 239 ++++++++++-------- 4 files changed, 154 insertions(+), 121 deletions(-) rename applications/system/js_app/modules/{js_uart.c => js_serial.c} (66%) diff --git a/applications/system/js_app/application.fam b/applications/system/js_app/application.fam index 29b4ebb59..5716234dc 100644 --- a/applications/system/js_app/application.fam +++ b/applications/system/js_app/application.fam @@ -33,9 +33,9 @@ App( ) App( - appid="js_uart", + appid="js_serial", apptype=FlipperAppType.PLUGIN, - entry_point="js_uart_ep", + entry_point="js_serial_ep", requires=["js_app"], - sources=["modules/js_uart.c"], + sources=["modules/js_serial.c"], ) diff --git a/applications/system/js_app/examples/apps/Scripts/bad_uart.js b/applications/system/js_app/examples/apps/Scripts/bad_uart.js index 8166c61f5..9396a3464 100644 --- a/applications/system/js_app/examples/apps/Scripts/bad_uart.js +++ b/applications/system/js_app/examples/apps/Scripts/bad_uart.js @@ -1,19 +1,19 @@ -let uart = require("uart"); -uart.setup(115200); +let serial = require("serial"); +serial.setup("lpuart", 115200); -// uart.write("\n"); -uart.write([0x0a]); -let console_resp = uart.expect("# ", 1000); +// serial.write("\n"); +serial.write([0x0a]); +let console_resp = serial.expect("# ", 1000); if (console_resp === undefined) { print("No CLI response"); } else { - uart.write("uci\n"); - let uci_state = uart.expect([": not found", "Usage: "]); + serial.write("uci\n"); + let uci_state = serial.expect([": not found", "Usage: "]); if (uci_state === 1) { - uart.expect("# "); - uart.write("uci show wireless\n"); - uart.expect(".key="); - print("key:", uart.readln()); + serial.expect("# "); + serial.write("uci show wireless\n"); + serial.expect(".key="); + print("key:", serial.readln()); } else { print("uci cmd not found"); } diff --git a/applications/system/js_app/examples/apps/Scripts/uart_echo.js b/applications/system/js_app/examples/apps/Scripts/uart_echo.js index 2f3957fd1..60d44d078 100644 --- a/applications/system/js_app/examples/apps/Scripts/uart_echo.js +++ b/applications/system/js_app/examples/apps/Scripts/uart_echo.js @@ -1,10 +1,10 @@ -let uart = require("uart"); -uart.setup(115200); +let serial = require("serial"); +serial.setup("usart", 230400); while (1) { - let rx_data = uart.readBytes(1, 0); + let rx_data = serial.readBytes(1, 0); if (rx_data !== undefined) { - uart.write(rx_data); + serial.write(rx_data); let data_view = Uint8Array(rx_data); print("0x" + to_hex_string(data_view[0])); } diff --git a/applications/system/js_app/modules/js_uart.c b/applications/system/js_app/modules/js_serial.c similarity index 66% rename from applications/system/js_app/modules/js_uart.c rename to applications/system/js_app/modules/js_serial.c index 8f251c276..4f1b14f98 100644 --- a/applications/system/js_app/modules/js_uart.c +++ b/applications/system/js_app/modules/js_serial.c @@ -3,7 +3,7 @@ #include "../js_modules.h" #include -#define TAG "js_uart" +#define TAG "js_serial" #define RX_BUF_LEN 2048 typedef struct { @@ -11,69 +11,99 @@ typedef struct { FuriStreamBuffer* rx_stream; FuriHalSerialHandle* serial_handle; struct mjs* mjs; -} JsUartInst; +} JsSerialInst; typedef struct { size_t len; char* data; } PatternArrayItem; +static const struct { + const char* name; + const FuriHalSerialId value; +} serial_channels[] = { + {"usart", FuriHalSerialIdUsart}, + {"lpuart", FuriHalSerialIdLpuart}, +}; + ARRAY_DEF(PatternArray, PatternArrayItem, M_POD_OPLIST); static void - js_uart_on_async_rx(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) { - JsUartInst* uart = context; - furi_assert(uart); + js_serial_on_async_rx(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) { + JsSerialInst* serial = context; + furi_assert(serial); if(event & FuriHalSerialRxEventData) { uint8_t data = furi_hal_serial_async_rx(handle); - furi_stream_buffer_send(uart->rx_stream, &data, 1, 0); - js_flags_set(uart->mjs, ThreadEventCustomDataRx); + furi_stream_buffer_send(serial->rx_stream, &data, 1, 0); + js_flags_set(serial->mjs, ThreadEventCustomDataRx); } } -static void js_uart_setup(struct mjs* mjs) { +static void js_serial_setup(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); - if(uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is already configured"); + if(serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is already configured"); mjs_return(mjs, MJS_UNDEFINED); return; } bool args_correct = false; + FuriHalSerialId serial_id = FuriHalSerialIdMax; uint32_t baudrate = 0; - if(mjs_nargs(mjs) == 1) { + do { + if(mjs_nargs(mjs) != 2) break; + mjs_val_t arg = mjs_arg(mjs, 0); - if(mjs_is_number(arg)) { - baudrate = mjs_get_int32(mjs, arg); - args_correct = true; + if(!mjs_is_string(arg)) break; + + size_t str_len = 0; + const char* arg_str = mjs_get_string(mjs, &arg, &str_len); + for(size_t i = 0; i < COUNT_OF(serial_channels); i++) { + size_t name_len = strlen(serial_channels[i].name); + if(str_len != name_len) continue; + if(strncmp(arg_str, serial_channels[i].name, str_len) == 0) { + serial_id = serial_channels[i].value; + break; + } } - } + if(serial_id == FuriHalSerialIdMax) { + break; + } + + arg = mjs_arg(mjs, 1); + if(!mjs_is_number(arg)) break; + baudrate = mjs_get_int32(mjs, arg); + + args_correct = true; + } while(0); + if(!args_correct) { mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_return(mjs, MJS_UNDEFINED); return; } - uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1); - uart->serial_handle = furi_hal_serial_control_acquire(FuriHalSerialIdLpuart); - if(uart->serial_handle) { - furi_hal_serial_init(uart->serial_handle, baudrate); - furi_hal_serial_async_rx_start(uart->serial_handle, js_uart_on_async_rx, uart, false); - uart->setup_done = true; + serial->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1); + serial->serial_handle = furi_hal_serial_control_acquire(serial_id); + if(serial->serial_handle) { + furi_hal_serial_init(serial->serial_handle, baudrate); + furi_hal_serial_async_rx_start( + serial->serial_handle, js_serial_on_async_rx, serial, false); + serial->setup_done = true; } } -static void js_uart_write(struct mjs* mjs) { +static void js_serial_write(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); - if(!uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is not configured"); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); + if(!serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured"); mjs_return(mjs, MJS_UNDEFINED); return; } @@ -90,14 +120,14 @@ static void js_uart_write(struct mjs* mjs) { args_correct = false; break; } - furi_hal_serial_tx(uart->serial_handle, (uint8_t*)arg_str, str_len); + furi_hal_serial_tx(serial->serial_handle, (uint8_t*)arg_str, str_len); } else if(mjs_is_number(arg)) { uint32_t byte_val = mjs_get_int32(mjs, arg); if(byte_val > 0xFF) { args_correct = false; break; } - furi_hal_serial_tx(uart->serial_handle, (uint8_t*)&byte_val, 1); + furi_hal_serial_tx(serial->serial_handle, (uint8_t*)&byte_val, 1); } else if(mjs_is_array(arg)) { size_t array_len = mjs_array_length(mjs, arg); for(size_t i = 0; i < array_len; i++) { @@ -111,7 +141,7 @@ static void js_uart_write(struct mjs* mjs) { args_correct = false; break; } - furi_hal_serial_tx(uart->serial_handle, (uint8_t*)&byte_val, 1); + furi_hal_serial_tx(serial->serial_handle, (uint8_t*)&byte_val, 1); } if(!args_correct) { break; @@ -123,7 +153,7 @@ static void js_uart_write(struct mjs* mjs) { } size_t len = 0; char* buf = mjs_array_buf_get_ptr(mjs, array_buf, &len); - furi_hal_serial_tx(uart->serial_handle, (uint8_t*)buf, len); + furi_hal_serial_tx(serial->serial_handle, (uint8_t*)buf, len); } else { args_correct = false; break; @@ -136,12 +166,12 @@ static void js_uart_write(struct mjs* mjs) { mjs_return(mjs, MJS_UNDEFINED); } -static size_t js_uart_receive(JsUartInst* uart, char* buf, size_t len, uint32_t timeout) { +static size_t js_serial_receive(JsSerialInst* serial, char* buf, size_t len, uint32_t timeout) { size_t bytes_read = 0; while(1) { uint32_t flags = ThreadEventCustomDataRx; - if(furi_stream_buffer_is_empty(uart->rx_stream)) { - flags = js_flags_wait(uart->mjs, ThreadEventCustomDataRx, timeout); + if(furi_stream_buffer_is_empty(serial->rx_stream)) { + flags = js_flags_wait(serial->mjs, ThreadEventCustomDataRx, timeout); } if(flags == 0) { // Timeout break; @@ -149,8 +179,8 @@ static size_t js_uart_receive(JsUartInst* uart, char* buf, size_t len, uint32_t bytes_read = 0; break; } else if(flags & ThreadEventCustomDataRx) { // New data received - size_t rx_len = - furi_stream_buffer_receive(uart->rx_stream, &buf[bytes_read], len - bytes_read, 0); + size_t rx_len = furi_stream_buffer_receive( + serial->rx_stream, &buf[bytes_read], len - bytes_read, 0); bytes_read += rx_len; if(bytes_read == len) { break; @@ -160,12 +190,12 @@ static size_t js_uart_receive(JsUartInst* uart, char* buf, size_t len, uint32_t return bytes_read; } -static void js_uart_read(struct mjs* mjs) { +static void js_serial_read(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); - if(!uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is not configured"); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); + if(!serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured"); mjs_return(mjs, MJS_UNDEFINED); return; } @@ -199,7 +229,7 @@ static void js_uart_read(struct mjs* mjs) { } char* read_buf = malloc(read_len); - size_t bytes_read = js_uart_receive(uart, read_buf, read_len, timeout); + size_t bytes_read = js_serial_receive(serial, read_buf, read_len, timeout); mjs_val_t return_obj = MJS_UNDEFINED; if(bytes_read > 0) { @@ -209,12 +239,12 @@ static void js_uart_read(struct mjs* mjs) { free(read_buf); } -static void js_uart_readln(struct mjs* mjs) { +static void js_serial_readln(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); - if(!uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is not configured"); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); + if(!serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured"); mjs_return(mjs, MJS_UNDEFINED); return; } @@ -246,7 +276,7 @@ static void js_uart_readln(struct mjs* mjs) { char read_char = 0; while(1) { - size_t read_len = js_uart_receive(uart, &read_char, 1, timeout); + size_t read_len = js_serial_receive(serial, &read_char, 1, timeout); if(read_len != 1) { break; } @@ -266,12 +296,12 @@ static void js_uart_readln(struct mjs* mjs) { furi_string_free(rx_buf); } -static void js_uart_read_bytes(struct mjs* mjs) { +static void js_serial_read_bytes(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); - if(!uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is not configured"); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); + if(!serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured"); mjs_return(mjs, MJS_UNDEFINED); return; } @@ -305,7 +335,7 @@ static void js_uart_read_bytes(struct mjs* mjs) { } char* read_buf = malloc(read_len); - size_t bytes_read = js_uart_receive(uart, read_buf, read_len, timeout); + size_t bytes_read = js_serial_receive(serial, read_buf, read_len, timeout); mjs_val_t return_obj = MJS_UNDEFINED; if(bytes_read > 0) { @@ -315,7 +345,8 @@ static void js_uart_read_bytes(struct mjs* mjs) { free(read_buf); } -static bool js_uart_expect_parse_string(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) { +static bool + js_serial_expect_parse_string(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) { size_t str_len = 0; const char* arg_str = mjs_get_string(mjs, &arg, &str_len); if((str_len == 0) || (arg_str == NULL)) { @@ -328,7 +359,7 @@ static bool js_uart_expect_parse_string(struct mjs* mjs, mjs_val_t arg, PatternA return true; } -static bool js_uart_expect_parse_array(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) { +static bool js_serial_expect_parse_array(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) { size_t array_len = mjs_array_length(mjs, arg); if(array_len == 0) { return false; @@ -357,7 +388,7 @@ static bool js_uart_expect_parse_array(struct mjs* mjs, mjs_val_t arg, PatternAr } static bool - js_uart_expect_parse_args(struct mjs* mjs, PatternArray_t patterns, uint32_t* timeout) { + js_serial_expect_parse_args(struct mjs* mjs, PatternArray_t patterns, uint32_t* timeout) { size_t num_args = mjs_nargs(mjs); if(num_args == 2) { mjs_val_t timeout_arg = mjs_arg(mjs, 1); @@ -370,7 +401,7 @@ static bool } mjs_val_t patterns_arg = mjs_arg(mjs, 0); if(mjs_is_string(patterns_arg)) { // Single string pattern - if(!js_uart_expect_parse_string(mjs, patterns_arg, patterns)) { + if(!js_serial_expect_parse_string(mjs, patterns_arg, patterns)) { return false; } } else if(mjs_is_array(patterns_arg)) { @@ -381,7 +412,7 @@ static bool mjs_val_t array_arg = mjs_array_get(mjs, patterns_arg, 0); if(mjs_is_number(array_arg)) { // Binary array pattern - if(!js_uart_expect_parse_array(mjs, patterns_arg, patterns)) { + if(!js_serial_expect_parse_array(mjs, patterns_arg, patterns)) { return false; } } else if((mjs_is_string(array_arg)) || (mjs_is_array(array_arg))) { // Multiple patterns @@ -389,11 +420,11 @@ static bool mjs_val_t arg = mjs_array_get(mjs, patterns_arg, i); if(mjs_is_string(arg)) { - if(!js_uart_expect_parse_string(mjs, arg, patterns)) { + if(!js_serial_expect_parse_string(mjs, arg, patterns)) { return false; } } else if(mjs_is_array(arg)) { - if(!js_uart_expect_parse_array(mjs, arg, patterns)) { + if(!js_serial_expect_parse_array(mjs, arg, patterns)) { return false; } } @@ -407,8 +438,10 @@ static bool return true; } -static int32_t - js_uart_expect_check_pattern_start(PatternArray_t patterns, char value, int32_t pattern_last) { +static int32_t js_serial_expect_check_pattern_start( + PatternArray_t patterns, + char value, + int32_t pattern_last) { size_t array_len = PatternArray_size(patterns); if((pattern_last + 1) >= (int32_t)array_len) { return (-1); @@ -421,12 +454,12 @@ static int32_t return (-1); } -static void js_uart_expect(struct mjs* mjs) { +static void js_serial_expect(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); - JsUartInst* uart = mjs_get_ptr(mjs, obj_inst); - furi_assert(uart); - if(!uart->setup_done) { - mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "UART is not configured"); + JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst); + furi_assert(serial); + if(!serial->setup_done) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured"); mjs_return(mjs, MJS_UNDEFINED); return; } @@ -436,7 +469,7 @@ static void js_uart_expect(struct mjs* mjs) { PatternArray_it_t it; PatternArray_init(patterns); - if(!js_uart_expect_parse_args(mjs, patterns, &timeout)) { + if(!js_serial_expect_parse_args(mjs, patterns, &timeout)) { mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_return(mjs, MJS_UNDEFINED); for(PatternArray_it(it, patterns); !PatternArray_end_p(it); PatternArray_next(it)) { @@ -464,12 +497,12 @@ static void js_uart_expect(struct mjs* mjs) { while(1) { if(buf_len == 0) { // Empty buffer - read by 1 byte to find pattern start - size_t bytes_read = js_uart_receive(uart, &compare_buf[0], 1, timeout); + size_t bytes_read = js_serial_receive(serial, &compare_buf[0], 1, timeout); if(bytes_read != 1) { is_timeout = true; break; } - pattern_candidate = js_uart_expect_check_pattern_start(patterns, compare_buf[0], -1); + pattern_candidate = js_serial_expect_check_pattern_start(patterns, compare_buf[0], -1); if(pattern_candidate == -1) { continue; } @@ -482,7 +515,7 @@ static void js_uart_expect(struct mjs* mjs) { pattern_found = pattern_candidate; for(size_t i = 0; i < pattern_cur->len; i++) { if(i >= buf_len) { - size_t bytes_read = js_uart_receive(uart, &compare_buf[i], 1, timeout); + size_t bytes_read = js_serial_receive(serial, &compare_buf[i], 1, timeout); if(bytes_read != 1) { is_timeout = true; break; @@ -500,14 +533,14 @@ static void js_uart_expect(struct mjs* mjs) { // Search other patterns with the same start char pattern_candidate = - js_uart_expect_check_pattern_start(patterns, compare_buf[0], pattern_candidate); + js_serial_expect_check_pattern_start(patterns, compare_buf[0], pattern_candidate); if(pattern_candidate >= 0) { continue; } // Look for another pattern start for(size_t i = 1; i < buf_len; i++) { - pattern_candidate = js_uart_expect_check_pattern_start(patterns, compare_buf[i], -1); + pattern_candidate = js_serial_expect_check_pattern_start(patterns, compare_buf[i], -1); if(pattern_candidate >= 0) { memmove(&compare_buf[0], &compare_buf[i], buf_len - i); buf_len -= i; @@ -539,47 +572,47 @@ static void js_uart_expect(struct mjs* mjs) { } } -static void* js_uart_create(struct mjs* mjs, mjs_val_t* object) { - JsUartInst* js_uart = malloc(sizeof(JsUartInst)); - js_uart->mjs = mjs; - mjs_val_t uart_obj = mjs_mk_object(mjs); - mjs_set(mjs, uart_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, js_uart)); - mjs_set(mjs, uart_obj, "setup", ~0, MJS_MK_FN(js_uart_setup)); - mjs_set(mjs, uart_obj, "write", ~0, MJS_MK_FN(js_uart_write)); - mjs_set(mjs, uart_obj, "read", ~0, MJS_MK_FN(js_uart_read)); - mjs_set(mjs, uart_obj, "readln", ~0, MJS_MK_FN(js_uart_readln)); - mjs_set(mjs, uart_obj, "readBytes", ~0, MJS_MK_FN(js_uart_read_bytes)); - mjs_set(mjs, uart_obj, "expect", ~0, MJS_MK_FN(js_uart_expect)); - *object = uart_obj; +static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) { + JsSerialInst* js_serial = malloc(sizeof(JsSerialInst)); + js_serial->mjs = mjs; + mjs_val_t serial_obj = mjs_mk_object(mjs); + mjs_set(mjs, serial_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, js_serial)); + mjs_set(mjs, serial_obj, "setup", ~0, MJS_MK_FN(js_serial_setup)); + mjs_set(mjs, serial_obj, "write", ~0, MJS_MK_FN(js_serial_write)); + mjs_set(mjs, serial_obj, "read", ~0, MJS_MK_FN(js_serial_read)); + mjs_set(mjs, serial_obj, "readln", ~0, MJS_MK_FN(js_serial_readln)); + mjs_set(mjs, serial_obj, "readBytes", ~0, MJS_MK_FN(js_serial_read_bytes)); + mjs_set(mjs, serial_obj, "expect", ~0, MJS_MK_FN(js_serial_expect)); + *object = serial_obj; - return js_uart; + return js_serial; } -static void js_uart_destroy(void* inst) { - JsUartInst* js_uart = inst; - if(js_uart->setup_done) { - furi_hal_serial_async_rx_stop(js_uart->serial_handle); - furi_hal_serial_deinit(js_uart->serial_handle); - furi_hal_serial_control_release(js_uart->serial_handle); - js_uart->serial_handle = NULL; +static void js_serial_destroy(void* inst) { + JsSerialInst* js_serial = inst; + if(js_serial->setup_done) { + furi_hal_serial_async_rx_stop(js_serial->serial_handle); + furi_hal_serial_deinit(js_serial->serial_handle); + furi_hal_serial_control_release(js_serial->serial_handle); + js_serial->serial_handle = NULL; } - furi_stream_buffer_free(js_uart->rx_stream); - free(js_uart); + furi_stream_buffer_free(js_serial->rx_stream); + free(js_serial); } -static const JsModuleDescriptor js_uart_desc = { - "uart", - js_uart_create, - js_uart_destroy, +static const JsModuleDescriptor js_serial_desc = { + "serial", + js_serial_create, + js_serial_destroy, }; static const FlipperAppPluginDescriptor plugin_descriptor = { .appid = PLUGIN_APP_ID, .ep_api_version = PLUGIN_API_VERSION, - .entry_point = &js_uart_desc, + .entry_point = &js_serial_desc, }; -const FlipperAppPluginDescriptor* js_uart_ep(void) { +const FlipperAppPluginDescriptor* js_serial_ep(void) { return &plugin_descriptor; } From dd87afcbde1187df1f0c43719122615d918986cc Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:55:28 +0300 Subject: [PATCH 5/8] Reduce subghz add manually scene flash size by @Willy-JL --- .../main/subghz/helpers/subghz_custom_event.h | 127 +- .../main/subghz/scenes/subghz_scene_set_cnt.c | 6 +- .../subghz/scenes/subghz_scene_set_seed.c | 12 +- .../subghz/scenes/subghz_scene_set_type.c | 1524 ++++++++--------- 4 files changed, 804 insertions(+), 865 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index ad26123ea..56bc7fe5f 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -5,68 +5,6 @@ typedef enum { SubGhzCustomEventManagerSet, SubGhzCustomEventManagerSetRAW, - //SubmenuIndex - SubmenuIndexFaacSLH_Manual_433, - SubmenuIndexFaacSLH_Manual_868, - SubmenuIndexFaacSLH_433, - SubmenuIndexFaacSLH_868, - SubmenuIndexBFTClone, - SubmenuIndexBFTMitto, - SubmenuIndexSomfyTelis, - SubmenuIndexBeninca433, - SubmenuIndexBeninca868, - SubmenuIndexAllmatic433, - SubmenuIndexAllmatic868, - SubmenuIndexCenturion433, - SubmenuIndexIronLogic, - SubmenuIndexElmesElectronic, - SubmenuIndexSommer_FM_434, - SubmenuIndexSommer_FM_868, - SubmenuIndexStilmatic, - SubmenuIndexDTMNeo433, - SubmenuIndexDeaMio433, - SubmenuIndexGibidi433, - SubmenuIndexNiceMHouse_433_92, - SubmenuIndexJCM_433_92, - SubmenuIndexFAACRCXT_433_92, - SubmenuIndexFAACRCXT_868, - SubmenuIndexNormstahl_433_92, - SubmenuIndexGeniusBravo433, - SubmenuIndexGSN, - SubmenuIndexAprimatic, - SubmenuIndexHCS101_433_92, - SubmenuIndexANMotorsAT4, - SubmenuIndexAlutechAT4N, - SubmenuIndexNiceFlo12bit, - SubmenuIndexNiceFlo24bit, - SubmenuIndexNiceFlorS_433_92, - SubmenuIndexNiceOne_433_92, - SubmenuIndexNiceSmilo_433_92, - SubmenuIndexCAME12bit, - SubmenuIndexCAME24bit, - SubmenuIndexCAME12bit868, - SubmenuIndexCAME24bit868, - SubmenuIndexCAMETwee, - SubmenuIndexCAMESpace, - SubmenuIndexCameAtomo433, - SubmenuIndexCameAtomo868, - SubmenuIndexPricenton433, - SubmenuIndexPricenton315, - SubmenuIndexBETT_433, - SubmenuIndexLinear_300_00, - SubmenuIndexNeroSketch, //Deleted in OFW - SubmenuIndexNeroRadio, //Deleted in OFW - SubmenuIndexGateTX, - SubmenuIndexDoorHan_315_00, - SubmenuIndexDoorHan_433_92, - SubmenuIndexSecPlus_v1_315_00, - SubmenuIndexSecPlus_v1_390_00, - SubmenuIndexSecPlus_v1_433_00, - SubmenuIndexSecPlus_v2_310_00, - SubmenuIndexSecPlus_v2_315_00, - SubmenuIndexSecPlus_v2_390_00, - SubmenuIndexSecPlus_v2_433_00, - //SubGhzCustomEvent SubGhzCustomEventSceneDeleteSuccess = 100, SubGhzCustomEventSceneDelete, @@ -123,3 +61,68 @@ typedef enum { SubGhzCustomEventByteInputDone, } SubGhzCustomEvent; + +typedef enum { + SetTypeFaacSLH_Manual_868, + SetTypeFaacSLH_Manual_433, + SetTypeBFTClone, + SetTypeFaacSLH_868, + SetTypeFaacSLH_433, + SetTypeBFTMitto, + SetTypeSomfyTelis, + SetTypeANMotorsAT4, + SetTypeAlutechAT4N, + SetTypeHCS101_433_92, + SetTypeDoorHan_315_00, + SetTypeDoorHan_433_92, + SetTypeBeninca433, + SetTypeBeninca868, + SetTypeAllmatic433, + SetTypeAllmatic868, + SetTypeCenturion433, + SetTypeSommer_FM_434, + SetTypeSommer_FM_868, + SetTypeStilmatic, + SetTypeIronLogic, + SetTypeDeaMio433, + SetTypeDTMNeo433, + SetTypeGibidi433, + SetTypeGSN, + SetTypeAprimatic, + SetTypeElmesElectronic, + SetTypeNormstahl_433_92, + SetTypeJCM_433_92, + SetTypeFAACRCXT_433_92, + SetTypeFAACRCXT_868, + SetTypeGeniusBravo433, + SetTypeNiceMHouse_433_92, + SetTypeNiceSmilo_433_92, + SetTypeNiceFlorS_433_92, + SetTypeNiceOne_433_92, + SetTypeNiceFlo12bit, + SetTypeNiceFlo24bit, + SetTypeCAME12bit, + SetTypeCAME24bit, + SetTypeCAME12bit868, + SetTypeCAME24bit868, + SetTypeCAMETwee, + SetTypeCameAtomo433, + SetTypeCameAtomo868, + SetTypeCAMESpace, + SetTypePricenton315, + SetTypePricenton433, + SetTypeBETT_433, + SetTypeLinear_300_00, + // SetTypeNeroSketch, //Deleted in OFW + // SetTypeNeroRadio, //Deleted in OFW + SetTypeGateTX, + SetTypeSecPlus_v1_315_00, + SetTypeSecPlus_v1_390_00, + SetTypeSecPlus_v1_433_00, + SetTypeSecPlus_v2_310_00, + SetTypeSecPlus_v2_315_00, + SetTypeSecPlus_v2_390_00, + SetTypeSecPlus_v2_433_00, + + SetTypeMAX, +} SetType; diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c index 0a07557fb..4952c2b14 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_set_cnt.c @@ -17,7 +17,7 @@ void subghz_scene_set_cnt_on_enter(void* context) { scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType); switch(state) { - case SubmenuIndexBFTClone: + case SetTypeBFTClone: byte_input_set_header_text(byte_input, "Enter COUNTER in Hex"); byte_input_set_result_callback( byte_input, @@ -27,8 +27,8 @@ void subghz_scene_set_cnt_on_enter(void* context) { subghz->secure_data->cnt, 2); break; - case SubmenuIndexFaacSLH_Manual_433: - case SubmenuIndexFaacSLH_Manual_868: + case SetTypeFaacSLH_Manual_433: + case SetTypeFaacSLH_Manual_868: byte_input_set_header_text(byte_input, "Enter COUNTER in Hex 20 bits"); byte_input_set_result_callback( byte_input, diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index c1f3662cb..a22daf919 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -32,11 +32,11 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { uint32_t fix_part, cnt, seed; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventByteInputDone) { - SubGhzCustomEvent state = + SetType state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType); switch(state) { - case SubmenuIndexBFTClone: + case SetTypeBFTClone: fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; @@ -62,8 +62,8 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; - case SubmenuIndexFaacSLH_Manual_433: - case SubmenuIndexFaacSLH_Manual_868: + case SetTypeFaacSLH_Manual_433: + case SetTypeFaacSLH_Manual_868: fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 | subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3]; @@ -73,7 +73,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 | subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3]; - if(state == SubmenuIndexFaacSLH_Manual_433) { + if(state == SetTypeFaacSLH_Manual_433) { generated_protocol = subghz_txrx_gen_faac_slh_protocol( subghz->txrx, "AM650", @@ -83,7 +83,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { (cnt & 0xFFFFF), seed, "FAAC_SLH"); - } else if(state == SubmenuIndexFaacSLH_Manual_868) { + } else if(state == SetTypeFaacSLH_Manual_868) { generated_protocol = subghz_txrx_gen_faac_slh_protocol( subghz->txrx, "AM650", diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 17f358fa6..90b30f076 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -10,361 +10,76 @@ void subghz_scene_set_type_submenu_callback(void* context, uint32_t index) { view_dispatcher_send_custom_event(subghz->view_dispatcher, index); } +static const char* submenu_names[SetTypeMAX] = { + [SetTypeFaacSLH_Manual_868] = "FAAC SLH [Man.] 868MHz", + [SetTypeFaacSLH_Manual_433] = "FAAC SLH [Man.] 433MHz", + [SetTypeBFTClone] = "BFT [Manual] 433MHz", + [SetTypeFaacSLH_868] = "FAAC SLH 868MHz", + [SetTypeFaacSLH_433] = "FAAC SLH 433MHz", + [SetTypeBFTMitto] = "BFT Mitto 433MHz", + [SetTypeSomfyTelis] = "Somfy Telis 433MHz", + [SetTypeANMotorsAT4] = "AN-Motors AT4 433MHz", + [SetTypeAlutechAT4N] = "Alutech AT4N 433MHz", + [SetTypeHCS101_433_92] = "KL: HCS101 433MHz", + [SetTypeDoorHan_315_00] = "KL: DoorHan 315MHz", + [SetTypeDoorHan_433_92] = "KL: DoorHan 433MHz", + [SetTypeBeninca433] = "KL: Beninca 433MHz", + [SetTypeBeninca868] = "KL: Beninca 868MHz", + [SetTypeAllmatic433] = "KL: Allmatic 433MHz", + [SetTypeAllmatic868] = "KL: Allmatic 868MHz", + [SetTypeCenturion433] = "KL: Centurion 433MHz", + [SetTypeSommer_FM_434] = "KL: Sommer 434MHz", + [SetTypeSommer_FM_868] = "KL: Sommer 868MHz", + [SetTypeStilmatic] = "KL: Stilmatic 433MHz", + [SetTypeIronLogic] = "KL: IronLogic 433MHz", + [SetTypeDeaMio433] = "KL: DEA Mio 433MHz", + [SetTypeDTMNeo433] = "KL: DTM Neo 433MHz", + [SetTypeGibidi433] = "KL: Gibidi 433MHz", + [SetTypeGSN] = "KL: GSN 433MHz", + [SetTypeAprimatic] = "KL: Aprimatic 433MHz", + [SetTypeElmesElectronic] = "KL: Elmes (PL) 433MHz", + [SetTypeNormstahl_433_92] = "KL: Normstahl 433MHz", + [SetTypeJCM_433_92] = "KL: JCM Tech 433MHz", + [SetTypeFAACRCXT_433_92] = "KL: FAAC RC,XT 433MHz", + [SetTypeFAACRCXT_868] = "KL: FAAC RC,XT 868MHz", + [SetTypeGeniusBravo433] = "KL: Genius Bravo 433MHz", + [SetTypeNiceMHouse_433_92] = "KL: Nice Mhouse 433MHz", + [SetTypeNiceSmilo_433_92] = "KL: Nice Smilo 433MHz", + [SetTypeNiceFlorS_433_92] = "Nice FloR-S 433MHz", + [SetTypeNiceOne_433_92] = "Nice One 433MHz", + [SetTypeNiceFlo12bit] = "Nice Flo 12bit 433MHz", + [SetTypeNiceFlo24bit] = "Nice Flo 24bit 433MHz", + [SetTypeCAME12bit] = "CAME 12bit 433MHz", + [SetTypeCAME24bit] = "CAME 24bit 433MHz", + [SetTypeCAME12bit868] = "CAME 12bit 868MHz", + [SetTypeCAME24bit868] = "CAME 24bit 868MHz", + [SetTypeCAMETwee] = "CAME TWEE 433MHz", + [SetTypeCameAtomo433] = "CAME Atomo 433MHz", + [SetTypeCameAtomo868] = "CAME Atomo 868MHz", + [SetTypeCAMESpace] = "KL: CAME Space 433MHz", + [SetTypePricenton315] = "Princeton 315MHz", + [SetTypePricenton433] = "Princeton 433MHz", + [SetTypeBETT_433] = "BETT 433MHz", + [SetTypeLinear_300_00] = "Linear 300MHz", + // [SetTypeNeroSketch] = "Nero Sketch", // Deleted in OFW + // [SetTypeNeroRadio] = "Nero Radio", // Deleted in OFW + [SetTypeGateTX] = "Gate TX 433MHz", + [SetTypeSecPlus_v1_315_00] = "Security+1.0 315MHz", + [SetTypeSecPlus_v1_390_00] = "Security+1.0 390MHz", + [SetTypeSecPlus_v1_433_00] = "Security+1.0 433MHz", + [SetTypeSecPlus_v2_310_00] = "Security+2.0 310MHz", + [SetTypeSecPlus_v2_315_00] = "Security+2.0 315MHz", + [SetTypeSecPlus_v2_390_00] = "Security+2.0 390MHz", + [SetTypeSecPlus_v2_433_00] = "Security+2.0 433MHz", +}; + void subghz_scene_set_type_on_enter(void* context) { SubGhz* subghz = context; - submenu_add_item( - subghz->submenu, - "FAAC SLH [Man.] 868MHz", - SubmenuIndexFaacSLH_Manual_868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "FAAC SLH [Man.] 433MHz", - SubmenuIndexFaacSLH_Manual_433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "BFT [Manual] 433MHz", - SubmenuIndexBFTClone, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "FAAC SLH 868MHz", - SubmenuIndexFaacSLH_868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "FAAC SLH 433MHz", - SubmenuIndexFaacSLH_433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "BFT Mitto 433MHz", - SubmenuIndexBFTMitto, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Somfy Telis 433MHz", - SubmenuIndexSomfyTelis, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "AN-Motors AT4 433MHz", - SubmenuIndexANMotorsAT4, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Alutech AT4N 433MHz", - SubmenuIndexAlutechAT4N, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: HCS101 433MHz", - SubmenuIndexHCS101_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: DoorHan 315MHz", - SubmenuIndexDoorHan_315_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: DoorHan 433MHz", - SubmenuIndexDoorHan_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Beninca 433MHz", - SubmenuIndexBeninca433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Beninca 868MHz", - SubmenuIndexBeninca868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Allmatic 433MHz", - SubmenuIndexAllmatic433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Allmatic 868MHz", - SubmenuIndexAllmatic868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Centurion 433MHz", - SubmenuIndexCenturion433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Sommer 434MHz", - SubmenuIndexSommer_FM_434, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Sommer 868MHz", - SubmenuIndexSommer_FM_868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Stilmatic 433MHz", - SubmenuIndexStilmatic, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: IronLogic 433MHz", - SubmenuIndexIronLogic, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: DEA Mio 433MHz", - SubmenuIndexDeaMio433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: DTM Neo 433MHz", - SubmenuIndexDTMNeo433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Gibidi 433MHz", - SubmenuIndexGibidi433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: GSN 433MHz", - SubmenuIndexGSN, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Aprimatic 433MHz", - SubmenuIndexAprimatic, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Elmes (PL) 433MHz", - SubmenuIndexElmesElectronic, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Normstahl 433MHz", - SubmenuIndexNormstahl_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: JCM Tech 433MHz", - SubmenuIndexJCM_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: FAAC RC,XT 433MHz", - SubmenuIndexFAACRCXT_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: FAAC RC,XT 868MHz", - SubmenuIndexFAACRCXT_868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Genius Bravo 433MHz", - SubmenuIndexGeniusBravo433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Nice Mhouse 433MHz", - SubmenuIndexNiceMHouse_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: Nice Smilo 433MHz", - SubmenuIndexNiceSmilo_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Nice FloR-S 433MHz", - SubmenuIndexNiceFlorS_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Nice One 433MHz", - SubmenuIndexNiceOne_433_92, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Nice Flo 12bit 433MHz", - SubmenuIndexNiceFlo12bit, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Nice Flo 24bit 433MHz", - SubmenuIndexNiceFlo24bit, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME 12bit 433MHz", - SubmenuIndexCAME12bit, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME 24bit 433MHz", - SubmenuIndexCAME24bit, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME 12bit 868MHz", - SubmenuIndexCAME12bit868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME 24bit 868MHz", - SubmenuIndexCAME24bit868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME TWEE 433MHz", - SubmenuIndexCAMETwee, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME Atomo 433MHz", - SubmenuIndexCameAtomo433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "CAME Atomo 868MHz", - SubmenuIndexCameAtomo868, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "KL: CAME Space 433MHz", - SubmenuIndexCAMESpace, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Princeton 315MHz", - SubmenuIndexPricenton315, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Princeton 433MHz", - SubmenuIndexPricenton433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "BETT 433MHz", - SubmenuIndexBETT_433, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Linear 300MHz", - SubmenuIndexLinear_300_00, - subghz_scene_set_type_submenu_callback, - subghz); - // submenu_add_item( - // subghz->submenu, "Nero Sketch", SubmenuIndexNeroSketch, subghz_scene_set_type_submenu_callback, subghz); - // submenu_add_item( - // subghz->submenu, "Nero Radio", SubmenuIndexNeroRadio, subghz_scene_set_type_submenu_callback, subghz); - submenu_add_item( - subghz->submenu, - "Gate TX 433MHz", - SubmenuIndexGateTX, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+1.0 315MHz", - SubmenuIndexSecPlus_v1_315_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+1.0 390MHz", - SubmenuIndexSecPlus_v1_390_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+1.0 433MHz", - SubmenuIndexSecPlus_v1_433_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+2.0 310MHz", - SubmenuIndexSecPlus_v2_310_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+2.0 315MHz", - SubmenuIndexSecPlus_v2_315_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+2.0 390MHz", - SubmenuIndexSecPlus_v2_390_00, - subghz_scene_set_type_submenu_callback, - subghz); - submenu_add_item( - subghz->submenu, - "Security+2.0 433MHz", - SubmenuIndexSecPlus_v2_433_00, - subghz_scene_set_type_submenu_callback, - subghz); + for(SetType i = 0; i < SetTypeMAX; i++) { + submenu_add_item( + subghz->submenu, submenu_names[i], i, subghz_scene_set_type_submenu_callback, subghz); + } submenu_set_selected_item( subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType)); @@ -372,521 +87,742 @@ void subghz_scene_set_type_on_enter(void* context) { view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdMenu); } +typedef enum { + GenData, + GenFaacSLH, + GenKeeloq, + GenCameAtomo, + GenKeeloqBFT, + GenAlutechAt4n, + GenSomfyTelis, + GenNiceFlorS, + GenSecPlus1, + GenSecPlus2, +} GenType; + +typedef struct { + GenType type; + const char* mod; + uint32_t freq; + union { + struct { + const char* name; + uint32_t key; + uint8_t bits; + uint16_t te; + } data; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + uint32_t seed; + const char* manuf; + } faac_slh; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + const char* manuf; + } keeloq; + struct { + uint32_t serial; + uint8_t cnt; + } came_atomo; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + uint32_t seed; + const char* manuf; + } keeloq_bft; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + } alutech_at_4n; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + } somfy_telis; + struct { + uint32_t serial; + uint8_t btn; + uint8_t cnt; + bool nice_one; + } nice_flor_s; + struct { + uint32_t serial; + uint8_t btn; + uint32_t cnt; + } sec_plus_2; + }; +} GenInfo; + bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; bool generated_protocol = false; if(event.type == SceneManagerEventTypeCustom) { + if(event.event >= SetTypeMAX) { + return false; + } + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSetType, event.event); + + if(event.event == SetTypeFaacSLH_Manual_868 || event.event == SetTypeFaacSLH_Manual_433 || + event.event == SetTypeBFTClone) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); + return true; + } + uint32_t key = (uint32_t)rand(); + GenInfo gen_info = {0}; switch(event.event) { - case SubmenuIndexFaacSLH_Manual_868: - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); + case SetTypePricenton433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 400}; break; - case SubmenuIndexFaacSLH_Manual_433: - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); + case SetTypePricenton315: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 315000000, + .data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 400}; break; - case SubmenuIndexBFTClone: - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix); + case SetTypeNiceFlo12bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; break; - case SubmenuIndexPricenton433: - key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - generated_protocol = subghz_txrx_gen_data_protocol_and_te( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400); + case SetTypeNiceFlo24bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; break; - case SubmenuIndexPricenton315: - key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - generated_protocol = subghz_txrx_gen_data_protocol_and_te( - subghz->txrx, "AM650", 315000000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400); + case SetTypeCAME12bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; break; - case SubmenuIndexNiceFlo12bit: - key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12); + case SetTypeCAME24bit: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; break; - case SubmenuIndexNiceFlo24bit: - key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24); + case SetTypeCAME12bit868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00000FF0) | 0x1, // btn 0x1, 0x2, 0x4 + .data.bits = 12, + .data.te = 0}; break; - case SubmenuIndexCAME12bit: - key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12); + case SetTypeCAME24bit868: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 868350000, + .data.name = SUBGHZ_PROTOCOL_CAME_NAME, + .data.key = (key & 0x00FFFFF0) | 0x4, // btn 0x1, 0x2, 0x4, 0x8 + .data.bits = 24, + .data.te = 0}; break; - case SubmenuIndexCAME24bit: - key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24); + case SetTypeLinear_300_00: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 300000000, + .data.name = SUBGHZ_PROTOCOL_LINEAR_NAME, + .data.key = (key & 0x3FF), + .data.bits = 10, + .data.te = 0}; break; - case SubmenuIndexCAME12bit868: - key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12); + case SetTypeBETT_433: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_BETT_NAME, + .data.key = (key & 0x0000FFF0), + .data.bits = 18, + .data.te = 0}; break; - case SubmenuIndexCAME24bit868: - key = (key & 0x00FFFFF0) | 0x4; //btn 0x1, 0x2, 0x4, 0x8 - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24); + case SetTypeCAMETwee: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_CAME_TWEE_NAME, + .data.key = 0x003FFF7200000000 | ((key & 0x0FFFFFF0) ^ 0xE0E0E0EE), // ???? + .data.bits = 54, + .data.te = 0}; break; - case SubmenuIndexLinear_300_00: - key = (key & 0x3FF); - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 300000000, SUBGHZ_PROTOCOL_LINEAR_NAME, key, 10); + case SetTypeGateTX: + gen_info = (GenInfo){ + .type = GenData, + .mod = "AM650", + .freq = 433920000, + .data.name = SUBGHZ_PROTOCOL_GATE_TX_NAME, // btn 0xF, 0xC, 0xA, 0x6 (?) + .data.key = subghz_protocol_blocks_reverse_key((key & 0x00F0FF00) | 0xF0040, 24), + .data.bits = 24, + .data.te = 0}; break; - case SubmenuIndexBETT_433: - key = (key & 0x0000FFF0); - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_BETT_NAME, key, 18); + case SetTypeFaacSLH_433: + gen_info = (GenInfo){ + .type = GenFaacSLH, + .mod = "AM650", + .freq = 433920000, + .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, + .faac_slh.btn = 0x06, + .faac_slh.cnt = 0x02, + .faac_slh.seed = key, + .faac_slh.manuf = "FAAC_SLH"}; break; - case SubmenuIndexCAMETwee: - key = (key & 0x0FFFFFF0); - key = 0x003FFF7200000000 | (key ^ 0xE0E0E0EE); - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_TWEE_NAME, key, 54); + case SetTypeFaacSLH_868: + gen_info = (GenInfo){ + .type = GenFaacSLH, + .mod = "AM650", + .freq = 868350000, + .faac_slh.serial = ((key & 0x00FFFFF0) | 0xA0000006) >> 4, + .faac_slh.btn = 0x06, + .faac_slh.cnt = 0x02, + .faac_slh.seed = key, + .faac_slh.manuf = "FAAC_SLH"}; break; - case SubmenuIndexGateTX: - key = (key & 0x00F0FF00) | 0xF << 16 | 0x40; //btn 0xF, 0xC, 0xA, 0x6 (?) - uint64_t rev_key = subghz_protocol_blocks_reverse_key(key, 24); - generated_protocol = subghz_txrx_gen_data_protocol( - subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24); + case SetTypeBeninca433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFF00) | 0x00800080, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; break; - case SubmenuIndexFaacSLH_433: - generated_protocol = subghz_txrx_gen_faac_slh_protocol( - subghz->txrx, - "AM650", - 433920000, - ((key & 0x00FFFFF0) | 0xA0000006) >> 4, - 0x6, - 0x00002, - key, - "FAAC_SLH"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeBeninca868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x000FFF00) | 0x00800080, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; break; - case SubmenuIndexFaacSLH_868: - generated_protocol = subghz_txrx_gen_faac_slh_protocol( - subghz->txrx, - "AM650", - 868350000, - ((key & 0x00FFFFF0) | 0xA0000006) >> 4, - 0x6, - 0x00002, - key, - "FAAC_SLH"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeAllmatic433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, + .keeloq.btn = 0x0C, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; break; - case SubmenuIndexBeninca433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x000FFF00) | 0x00800080, - 0x1, - 0x0005, - "Beninca"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeAllmatic868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x00FFFF00) | 0x01000011, + .keeloq.btn = 0x0C, + .keeloq.cnt = 0x05, + .keeloq.manuf = "Beninca"}; break; - case SubmenuIndexBeninca868: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 868350000, - (key & 0x000FFF00) | 0x00800080, - 0x1, - 0x0005, - "Beninca"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeCenturion433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF), + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Centurion"}; break; - case SubmenuIndexAllmatic433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x00FFFF00) | 0x01000011, - 0xC, - 0x0005, - "Beninca"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeElmesElectronic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x00FFFFFF) | 0x02000000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Elmes_Poland"}; break; - case SubmenuIndexAllmatic868: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 868350000, - (key & 0x00FFFF00) | 0x01000011, - 0xC, - 0x0005, - "Beninca"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeANMotorsAT4: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF) | 0x04700000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x21, + .keeloq.manuf = "AN-Motors"}; break; - case SubmenuIndexCenturion433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, (key & 0x0000FFFF), 0x2, 0x0003, "Centurion"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeAprimatic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x000FFFFF) | 0x00600000, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Aprimatic"}; break; - case SubmenuIndexElmesElectronic: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x00FFFFFF) | 0x02000000, - 0x2, - 0x0003, - "Elmes_Poland"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeGibidi433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Gibidi"}; break; - case SubmenuIndexANMotorsAT4: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x000FFFFF) | 0x04700000, - 0x2, - 0x0021, - "AN-Motors"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeGSN: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "GSN"}; break; - case SubmenuIndexAprimatic: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x000FFFFF) | 0x00600000, - 0x4, - 0x0003, - "Aprimatic"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeIronLogic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFF0, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x05, + .keeloq.manuf = "IronLogic"}; break; - case SubmenuIndexGibidi433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Gibidi"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeStilmatic: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x01, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Stilmatic"}; break; - case SubmenuIndexGSN: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "GSN"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeSommer_FM_434: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM476", + .freq = 434420000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; break; - case SubmenuIndexIronLogic: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFF0, 0x4, 0x0005, "IronLogic"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeSommer_FM_868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "FM476", + .freq = 868800000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Sommer(fsk476)"}; break; - case SubmenuIndexStilmatic: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, "Stilmatic"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeDTMNeo433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x000FFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x05, + .keeloq.manuf = "DTM_Neo"}; break; - case SubmenuIndexSommer_FM_434: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "FM476", 434420000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeCAMESpace: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Came_Space"}; break; - case SubmenuIndexSommer_FM_868: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "FM476", 868800000, key & 0x0FFFFFFF, 0x4, 0x0003, "Sommer(fsk476)"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeCameAtomo433: + gen_info = (GenInfo){ + .type = GenCameAtomo, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0FFFFFFF) | 0x10000000, + .keeloq.cnt = 0x03}; break; - case SubmenuIndexDTMNeo433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0005, "DTM_Neo"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeCameAtomo868: + gen_info = (GenInfo){ + .type = GenCameAtomo, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x0FFFFFFF) | 0x10000000, + .keeloq.cnt = 0x03}; break; - case SubmenuIndexCAMESpace: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Came_Space"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeBFTMitto: + gen_info = (GenInfo){ + .type = GenKeeloqBFT, + .mod = "AM650", + .freq = 433920000, + .keeloq_bft.serial = key & 0x000FFFFF, + .keeloq_bft.btn = 0x02, + .keeloq_bft.cnt = 0x02, + .keeloq_bft.seed = key & 0x000FFFFF, + .keeloq_bft.manuf = "BFT"}; break; - case SubmenuIndexCameAtomo433: - generated_protocol = subghz_txrx_gen_came_atomo_protocol( - subghz->txrx, "AM650", 433920000, (key & 0x0FFFFFFF) | 0x10000000, 0x0003); + case SetTypeAlutechAT4N: + gen_info = (GenInfo){ + .type = GenAlutechAt4n, + .mod = "AM650", + .freq = 433920000, + .alutech_at_4n.serial = (key & 0x000FFFFF) | 0x00100000, + .alutech_at_4n.btn = 0x44, + .alutech_at_4n.cnt = 0x03}; break; - case SubmenuIndexCameAtomo868: - generated_protocol = subghz_txrx_gen_came_atomo_protocol( - subghz->txrx, "AM650", 868350000, (key & 0x0FFFFFFF) | 0x10000000, 0x0003); + case SetTypeSomfyTelis: + gen_info = (GenInfo){ + .type = GenSomfyTelis, + .mod = "AM650", + .freq = 433420000, + .somfy_telis.serial = key & 0x00FFFFFF, + .somfy_telis.btn = 0x02, + .somfy_telis.cnt = 0x03}; break; - case SubmenuIndexBFTMitto: - generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( - subghz->txrx, - "AM650", - 433920000, - key & 0x000FFFFF, - 0x2, - 0x0002, - key & 0x000FFFFF, - "BFT"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeDoorHan_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "DoorHan"}; break; - case SubmenuIndexAlutechAT4N: - generated_protocol = subghz_txrx_gen_alutech_at_4n_protocol( - subghz->txrx, "AM650", 433920000, (key & 0x000FFFFF) | 0x00100000, 0x44, 0x0003); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeDoorHan_315_00: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 315000000, + .keeloq.serial = key & 0x0FFFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "DoorHan"}; break; - case SubmenuIndexSomfyTelis: - generated_protocol = subghz_txrx_gen_somfy_telis_protocol( - subghz->txrx, "AM650", 433420000, key & 0x00FFFFFF, 0x2, 0x0003); + case SetTypeNiceFlorS_433_92: + gen_info = (GenInfo){ + .type = GenNiceFlorS, + .mod = "AM650", + .freq = 433920000, + .nice_flor_s.serial = key & 0x0FFFFFFF, + .nice_flor_s.btn = 0x01, + .nice_flor_s.cnt = 0x03, + .nice_flor_s.nice_one = false}; break; - case SubmenuIndexDoorHan_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeNiceOne_433_92: + gen_info = (GenInfo){ + .type = GenNiceFlorS, + .mod = "AM650", + .freq = 433920000, + .nice_flor_s.serial = key & 0x0FFFFFFF, + .nice_flor_s.btn = 0x01, + .nice_flor_s.cnt = 0x03, + .nice_flor_s.nice_one = true}; break; - case SubmenuIndexDoorHan_315_00: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 315000000, key & 0x0FFFFFFF, 0x2, 0x0003, "DoorHan"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeNiceSmilo_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "NICE_Smilo"}; break; - case SubmenuIndexNiceFlorS_433_92: - generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( - subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, false); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeNiceMHouse_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "NICE_MHOUSE"}; break; - case SubmenuIndexNiceOne_433_92: - generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( - subghz->txrx, "AM650", 433920000, key & 0x0FFFFFFF, 0x1, 0x0003, true); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeDeaMio433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0FFFF000) | 0x00000869, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Dea_Mio"}; break; - case SubmenuIndexNiceSmilo_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_Smilo"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeGeniusBravo433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x06, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Genius_Bravo"}; break; - case SubmenuIndexNiceMHouse_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_MHOUSE"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeJCM_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "JCM_Tech"}; break; - case SubmenuIndexDeaMio433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x0FFFF000) | 0x00000869, - 0x2, - 0x0003, - "Dea_Mio"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeFAACRCXT_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "FAAC_RC,XT"}; break; - case SubmenuIndexGeniusBravo433: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x6, 0x0003, "Genius_Bravo"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeFAACRCXT_868: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 868350000, + .keeloq.serial = (key & 0x0000FFFF) | 0x00100000, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "FAAC_RC,XT"}; break; - case SubmenuIndexJCM_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "JCM_Tech"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeNormstahl_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Normstahl"}; break; - case SubmenuIndexFAACRCXT_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 433920000, - (key & 0x0000FFFF) | 0x00100000, - 0x2, - 0x0003, - "FAAC_RC,XT"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeHCS101_433_92: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x000FFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "HCS101"}; break; - case SubmenuIndexFAACRCXT_868: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, - "AM650", - 868350000, - (key & 0x0000FFFF) | 0x00100000, - 0x2, - 0x0003, - "FAAC_RC,XT"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeSecPlus_v1_315_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 315000000}; break; - case SubmenuIndexNormstahl_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Normstahl"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeSecPlus_v1_390_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 390000000}; break; - case SubmenuIndexHCS101_433_92: - generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0003, "HCS101"); - if(!generated_protocol) { - furi_string_set( - subghz->error_str, "Function requires\nan SD card with\nfresh databases."); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); - } + case SetTypeSecPlus_v1_433_00: + gen_info = (GenInfo){.type = GenSecPlus1, .mod = "AM650", .freq = 433920000}; break; - case SubmenuIndexSecPlus_v1_315_00: - generated_protocol = - subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 315000000); + case SetTypeSecPlus_v2_310_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 310000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; break; - case SubmenuIndexSecPlus_v1_390_00: - generated_protocol = - subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 390000000); + case SetTypeSecPlus_v2_315_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 315000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; break; - case SubmenuIndexSecPlus_v1_433_00: - generated_protocol = - subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 433920000); + case SetTypeSecPlus_v2_390_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 390000000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; break; - case SubmenuIndexSecPlus_v2_310_00: - key = (key & 0x7FFFF3FC); // 850LM pairing - generated_protocol = subghz_txrx_gen_secplus_v2_protocol( - subghz->txrx, "AM650", 310000000, key, 0x68, 0xE500000); - break; - case SubmenuIndexSecPlus_v2_315_00: - key = (key & 0x7FFFF3FC); // 850LM pairing - generated_protocol = subghz_txrx_gen_secplus_v2_protocol( - subghz->txrx, "AM650", 315000000, key, 0x68, 0xE500000); - break; - case SubmenuIndexSecPlus_v2_390_00: - key = (key & 0x7FFFF3FC); // 850LM pairing - generated_protocol = subghz_txrx_gen_secplus_v2_protocol( - subghz->txrx, "AM650", 390000000, key, 0x68, 0xE500000); - break; - case SubmenuIndexSecPlus_v2_433_00: - key = (key & 0x7FFFF3FC); // 850LM pairing - generated_protocol = subghz_txrx_gen_secplus_v2_protocol( - subghz->txrx, "AM650", 433920000, key, 0x68, 0xE500000); + case SetTypeSecPlus_v2_433_00: + gen_info = (GenInfo){ + .type = GenSecPlus2, + .mod = "AM650", + .freq = 433920000, + .sec_plus_2.serial = (key & 0x7FFFF3FC), // 850LM pairing + .sec_plus_2.btn = 0x68, + .sec_plus_2.cnt = 0xE500000}; break; default: - return false; + furi_crash("Not implemented"); break; } - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneSetType, event.event); + switch(gen_info.type) { + case GenData: + if(gen_info.data.te) { + generated_protocol = subghz_txrx_gen_data_protocol_and_te( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.data.name, + gen_info.data.key, + gen_info.data.bits, + gen_info.data.te); + } else { + generated_protocol = subghz_txrx_gen_data_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.data.name, + gen_info.data.key, + gen_info.data.bits); + } + break; + case GenFaacSLH: + generated_protocol = subghz_txrx_gen_faac_slh_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.faac_slh.serial, + gen_info.faac_slh.btn, + gen_info.faac_slh.cnt, + gen_info.faac_slh.seed, + gen_info.faac_slh.manuf); + break; + case GenKeeloq: + generated_protocol = subghz_txrx_gen_keeloq_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.keeloq.serial, + gen_info.keeloq.btn, + gen_info.keeloq.cnt, + gen_info.keeloq.manuf); + break; + case GenCameAtomo: + generated_protocol = subghz_txrx_gen_came_atomo_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.came_atomo.serial, + gen_info.came_atomo.cnt); + break; + case GenKeeloqBFT: + generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.keeloq_bft.serial, + gen_info.keeloq_bft.btn, + gen_info.keeloq_bft.cnt, + gen_info.keeloq_bft.seed, + gen_info.keeloq_bft.manuf); + break; + case GenAlutechAt4n: + generated_protocol = subghz_txrx_gen_alutech_at_4n_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.alutech_at_4n.serial, + gen_info.alutech_at_4n.btn, + gen_info.alutech_at_4n.cnt); + break; + case GenSomfyTelis: + generated_protocol = subghz_txrx_gen_somfy_telis_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.somfy_telis.serial, + gen_info.somfy_telis.btn, + gen_info.somfy_telis.cnt); + break; + case GenNiceFlorS: + generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.nice_flor_s.serial, + gen_info.nice_flor_s.btn, + gen_info.nice_flor_s.cnt, + gen_info.nice_flor_s.nice_one); + break; + case GenSecPlus1: + generated_protocol = + subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, gen_info.mod, gen_info.freq); + break; + case GenSecPlus2: + generated_protocol = subghz_txrx_gen_secplus_v2_protocol( + subghz->txrx, + gen_info.mod, + gen_info.freq, + gen_info.sec_plus_2.serial, + gen_info.sec_plus_2.btn, + gen_info.sec_plus_2.cnt); + break; + default: + furi_crash("Not implemented"); + break; + } if(generated_protocol) { subghz_file_name_clear(subghz); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); - return true; + } else { + furi_string_set( + subghz->error_str, "Function requires\nan SD card with\nfresh databases."); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } - return false; + return generated_protocol; } void subghz_scene_set_type_on_exit(void* context) { From d75f2c62cad0c6a2dcf5d6cf3ad33387ee9b620a Mon Sep 17 00:00:00 2001 From: nminaylov Date: Tue, 13 Feb 2024 16:05:04 +0300 Subject: [PATCH 6/8] JS debug disabled, archive and file browser fixes --- applications/main/archive/helpers/archive_files.c | 2 +- applications/services/gui/modules/file_browser_worker.c | 1 + applications/system/js_app/js_thread.c | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index a8bd937c9..0d32e37bf 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -15,7 +15,7 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder } else { for(size_t i = 0; i < COUNT_OF(known_ext); i++) { if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue; - if(furi_string_search(file->path, known_ext[i], 0) != FURI_STRING_FAILURE) { + if(furi_string_end_with(file->path, known_ext[i])) { if(i == ArchiveFileTypeBadUsb) { if(furi_string_search( file->path, archive_get_default_path(ArchiveTabBadUsb)) == 0) { diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 2636c9555..b5d8aee9a 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -80,6 +80,7 @@ static bool browser_path_trim(FuriString* path) { return is_root; } static void browser_parse_ext_filter(ExtFilterArray_t ext_filter, const char* filter_str) { + ExtFilterArray_reset(ext_filter); if(!filter_str) { return; } diff --git a/applications/system/js_app/js_thread.c b/applications/system/js_app/js_thread.c index 22007d013..5ca365404 100644 --- a/applications/system/js_app/js_thread.c +++ b/applications/system/js_app/js_thread.c @@ -210,6 +210,7 @@ static void js_global_to_hex_string(struct mjs* mjs) { mjs_return(mjs, ret); } +#ifdef JS_DEBUG static void js_dump_write_callback(void* ctx, const char* format, ...) { File* file = ctx; furi_assert(ctx); @@ -225,6 +226,7 @@ static void js_dump_write_callback(void* ctx, const char* format, ...) { storage_file_write(file, furi_string_get_cstr(str), furi_string_size(str)); furi_string_free(str); } +#endif static int32_t js_thread(void* arg) { JsThread* worker = arg; @@ -255,6 +257,7 @@ static int32_t js_thread(void* arg) { mjs_err_t err = mjs_exec_file(mjs, furi_string_get_cstr(worker->path), NULL); +#ifdef JS_DEBUG if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { FuriString* dump_path = furi_string_alloc_set(worker->path); furi_string_cat(dump_path, ".lst"); @@ -273,6 +276,7 @@ static int32_t js_thread(void* arg) { furi_string_free(dump_path); } +#endif if(err != MJS_OK) { FURI_LOG_E(TAG, "Exec error: %s", mjs_strerror(mjs, err)); From 4042852825dffe657cfc8db6c7a57af9bb4972ce Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 13 Feb 2024 11:33:13 +0000 Subject: [PATCH 7/8] text box: reserve correct memory size to avoid reallocation --- applications/services/gui/modules/text_box.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/applications/services/gui/modules/text_box.c b/applications/services/gui/modules/text_box.c index 0e4aae944..e23fda09f 100644 --- a/applications/services/gui/modules/text_box.c +++ b/applications/services/gui/modules/text_box.c @@ -4,6 +4,9 @@ #include #include +#define TEXT_BOX_MAX_SYMBOL_WIDTH (10) +#define TEXT_BOX_LINE_WIDTH (120) + struct TextBox { View* view; @@ -78,13 +81,11 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { const char* str = model->text; size_t line_num = 0; - const size_t text_width = 120; - while(str[i] != '\0') { char symb = str[i++]; if(symb != '\n') { size_t glyph_width = canvas_glyph_width(canvas, symb); - if(line_width + glyph_width > text_width) { + if(line_width + glyph_width > TEXT_BOX_LINE_WIDTH) { line_num++; line_width = 0; furi_string_push_back(model->text_formatted, '\n'); @@ -211,6 +212,7 @@ void text_box_reset(TextBox* text_box) { furi_string_set(model->text_formatted, ""); model->font = TextBoxFontText; model->focus = TextBoxFocusStart; + model->formatted = false; }, true); } @@ -218,6 +220,8 @@ void text_box_reset(TextBox* text_box) { void text_box_set_text(TextBox* text_box, const char* text) { furi_assert(text_box); furi_assert(text); + size_t str_length = strlen(text); + size_t formating_margin = str_length * TEXT_BOX_MAX_SYMBOL_WIDTH / TEXT_BOX_LINE_WIDTH; with_view_model( text_box->view, @@ -225,7 +229,7 @@ void text_box_set_text(TextBox* text_box, const char* text) { { model->text = text; furi_string_reset(model->text_formatted); - furi_string_reserve(model->text_formatted, strlen(text)); + furi_string_reserve(model->text_formatted, str_length + formating_margin); model->formatted = false; }, true); From fdde5856b8660558ff26414c7c75522434a71dce Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:48:49 +0300 Subject: [PATCH 8/8] upd docs --- ReadMe.md | 2 +- documentation/SubGHzRemoteProg.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index f0e45d585..9f3bcc872 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -61,7 +61,7 @@ - **Hold right in received signal list to delete selected signal** - **Custom buttons for Keeloq / Alutech AT4N / Nice Flor S / Somfy Telis / Security+ 2.0 / CAME Atomo** - now you can use arrow buttons to send signal with different button code - `Add manually` menu extended with new protocols - - FAAC SLH, BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis) + - FAAC SLH, BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis, (right arrow button for other protocols)) - Debug mode counter increase settings (+1 -> +5, +10, default: +1) - Debug PIN output settings for protocol development diff --git a/documentation/SubGHzRemoteProg.md b/documentation/SubGHzRemoteProg.md index 0a799fc58..1c14678f5 100644 --- a/documentation/SubGHzRemoteProg.md +++ b/documentation/SubGHzRemoteProg.md @@ -29,6 +29,13 @@ SEED -> Your seed from the remote button you got earlier 8. Flipper will act as new remote, press Send button couple times near the receiver to register new remote 9. Done! +## Dea Mio +1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> Dea Mio 433Mhz +2. Open your new remote file +3. Right arrow button on the flipper simulates press of hidden button in original remote +4. Send button simulates one of basic buttons of the remote, can be programmed into the receiver +5. Follow manufacturer instructions on new remotes programming + ## AN-Motors AT4 **This instruction for older boards, if your has no** `Learn` **button but has buttons** `F`, `CL`, `+`, `-` **read instruction from Alutech AT4N**