diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index abca098eb..e24ed8f7a 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -794,12 +794,17 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb subghz_device_cc1101_ext->async_tx.buffer = malloc(SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + // here we do the same things as in /unleashed-firmware/targets/f7/furi_hal/furi_hal_subghz.c + // use first DMA to update timer TIM17 durations, but TIM17 have not output chanel + // so we use second DMA to transfer data from gpio_tx_buff directly to gpio pin using BSSR. + // BSSR allow us tranfer data directly to pin in gpio port. + //Signal generation with mem-to-mem DMA furi_hal_gpio_write(subghz_device_cc1101_ext->g0_pin, false); furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - // Configure DMA update timer + // Configure DMA to update timer TIM17 ARR by durations from buffer LL_DMA_SetMemoryAddress( SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF, (uint32_t)subghz_device_cc1101_ext->async_tx.buffer); LL_DMA_SetPeriphAddress(SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF, (uint32_t) & (TIM17->ARR)); @@ -821,7 +826,7 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb furi_hal_bus_enable(FuriHalBusTIM17); - // Configure TIM + // Configure TIM 17 // Set the timer resolution to 2 us LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP); LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1); @@ -835,7 +840,7 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb subghz_device_cc1101_ext_async_tx_refill( subghz_device_cc1101_ext->async_tx.buffer, SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL); - // Configure tx gpio dma + // Configure DMA to transfer data from gpio_tx_buff directly to gpio pin using BSSR const GpioPin* gpio = subghz_device_cc1101_ext->g0_pin; subghz_device_cc1101_ext->async_tx.gpio_tx_buff[0] = (uint32_t)gpio->pin << GPIO_NUMBER; diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 8abf373f4..ca3f0b300 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -234,7 +234,6 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers; FuriString* temp_str = furi_string_alloc(); - uint32_t repeat = 200; do { if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -244,10 +243,6 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* FURI_LOG_E(TAG, "Missing Protocol"); break; } - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } ret = SubGhzTxRxStartTxStateOk; SubGhzRadioPreset* preset = instance->preset; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index e68b0203d..26b4d4600 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -2,8 +2,12 @@ #include +#include "applications/main/subghz/helpers/subghz_txrx_i.h" + #define TAG "SubGhzSceneReceiverInfo" +static bool tx_stop_called = false; + void subghz_scene_receiver_info_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); SubGhz* subghz = context; @@ -138,8 +142,17 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) return true; } else if(event.event == SubGhzCustomEventSceneReceiverInfoTxStop) { //CC1101 Stop Tx -> Start RX + + // if we recieve event to stop tranmission (user release OK button) but + // hardware TX still working now then set flag to stop it after hardware TX will be realy ended + // else stop TX correctly and start RX + if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) { + tx_stop_called = true; + return true; + } subghz->state_notifications = SubGhzNotificationStateIDLE; + //update screen data widget_reset(subghz->widget); subghz_scene_receiver_info_draw_widget(subghz); @@ -179,7 +192,57 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) } switch(subghz->state_notifications) { case SubGhzNotificationStateTx: - notification_message(subghz->notifications, &sequence_blink_magenta_10); + // if hardware TX still working at this time so we just blink led and do nothing + if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) { + notification_message(subghz->notifications, &sequence_blink_magenta_10); + return true; + } + // if hardware TX not working now and tx_stop_called = true + // (mean user release OK button early than hardware TX was ended) then we stop TX + if(tx_stop_called) { + tx_stop_called = false; + subghz->state_notifications = SubGhzNotificationStateIDLE; + + //update screen data + widget_reset(subghz->widget); + subghz_scene_receiver_info_draw_widget(subghz); + + subghz_txrx_stop(subghz->txrx); + + // Start RX + if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) { + subghz_txrx_rx_start(subghz->txrx); + + subghz_txrx_hopper_unpause(subghz->txrx); + if(!subghz_history_get_text_space_left(subghz->history, NULL)) { + subghz->state_notifications = SubGhzNotificationStateRx; + } + } + return true; + } else { + // if current state == SubGhzNotificationStateTx but hardware TX was ended + // and user still not release OK button then we repeat TX + + subghz->state_notifications = SubGhzNotificationStateIDLE; + + //update screen data + widget_reset(subghz->widget); + subghz_scene_receiver_info_draw_widget(subghz); + + //CC1101 Stop RX -> Start TX + subghz_txrx_hopper_pause(subghz->txrx); + if(!subghz_tx_start( + subghz, + subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen))) { + subghz_txrx_rx_start(subghz->txrx); + subghz_txrx_hopper_unpause(subghz->txrx); + subghz->state_notifications = SubGhzNotificationStateRx; + } else { + subghz->state_notifications = SubGhzNotificationStateTx; + } + + return true; + } break; case SubGhzNotificationStateRx: notification_message(subghz->notifications, &sequence_blink_cyan_10); diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index ebd69059f..bfb974417 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -3,9 +3,14 @@ #include #include +#include + +#include "applications/main/subghz/helpers/subghz_txrx_i.h" #define TAG "SubGhzSceneTransmitter" +static bool tx_stop_called = false; + void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; @@ -66,6 +71,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventViewTransmitterSendStart) { + // if we recieve event to start transmission (user press OK button) then start/restart TX subghz->state_notifications = SubGhzNotificationStateIDLE; if(subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx))) { @@ -75,6 +81,13 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { } return true; } else if(event.event == SubGhzCustomEventViewTransmitterSendStop) { + // if we recieve event to stop tranmission (user release OK button) but + // hardware TX still working now then set flag to stop it after hardware TX will be realy ended + if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) { + tx_stop_called = true; + return true; + } + // if hardware TX not working now so just stop TX correctly subghz->state_notifications = SubGhzNotificationStateIDLE; subghz_txrx_stop(subghz->txrx); if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) { @@ -92,6 +105,10 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { } return true; } else if(event.event == SubGhzCustomEventViewTransmitterBack) { + // if user press back button then force stop TX if they was active + if(subghz->state_notifications == SubGhzNotificationStateTx) { + subghz_txrx_stop(subghz->txrx); + } subghz->state_notifications = SubGhzNotificationStateIDLE; scene_manager_search_and_switch_to_previous_scene( subghz->scene_manager, SubGhzSceneStart); @@ -102,7 +119,42 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { } } else if(event.type == SceneManagerEventTypeTick) { if(subghz->state_notifications == SubGhzNotificationStateTx) { - notification_message(subghz->notifications, &sequence_blink_magenta_10); + // if hardware TX still working at this time so we just blink led and do nothing + if(!subghz_devices_is_async_complete_tx(subghz->txrx->radio_device)) { + notification_message(subghz->notifications, &sequence_blink_magenta_10); + return true; + } + // if hardware TX not working now and tx_stop_called = true + // (mean user release OK button early than hardware TX was ended) then we stop TX + if(tx_stop_called) { + tx_stop_called = false; + subghz->state_notifications = SubGhzNotificationStateIDLE; + subghz_txrx_stop(subghz->txrx); + if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) { + subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK); + int32_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult(); + furi_hal_subghz_set_rolling_counter_mult(0); + // Calling restore! + subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); + subghz_txrx_stop(subghz->txrx); + // Calling restore 2nd time special for FAAC SLH! + // TODO: Find better way to restore after custom button is used!!! + subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); + subghz_txrx_stop(subghz->txrx); + furi_hal_subghz_set_rolling_counter_mult(tmp_counter); + } + return true; + } else { + // if current state == SubGhzNotificationStateTx but hardware TX was ended + // and user still not release OK button then we repeat transmission + subghz->state_notifications = SubGhzNotificationStateIDLE; + if(subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx))) { + subghz->state_notifications = SubGhzNotificationStateTx; + subghz_scene_transmitter_update_data_show(subghz); + dolphin_deed(DolphinDeedSubGhzSend); + } + return true; + } } return true; } diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 687a1e930..21ad71f01 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -94,7 +94,7 @@ void* subghz_protocol_encoder_alutech_at_4n_alloc(SubGhzEnvironment* environment instance->base.protocol = &subghz_protocol_alutech_at_4n; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/ansonic.c b/lib/subghz/protocols/ansonic.c index 75f803370..176ebe0bc 100644 --- a/lib/subghz/protocols/ansonic.c +++ b/lib/subghz/protocols/ansonic.c @@ -150,6 +150,7 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Deserialize error"); break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/beninca_arc.c b/lib/subghz/protocols/beninca_arc.c index 83db66306..786de5fa8 100644 --- a/lib/subghz/protocols/beninca_arc.c +++ b/lib/subghz/protocols/beninca_arc.c @@ -256,7 +256,7 @@ void* subghz_protocol_encoder_beninca_arc_alloc(SubGhzEnvironment* environment) instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - instance->encoder.repeat = 10; + instance->encoder.repeat = 1; instance->encoder.size_upload = 800; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/bett.c b/lib/subghz/protocols/bett.c index 44946a2f6..277d75bd0 100644 --- a/lib/subghz/protocols/bett.c +++ b/lib/subghz/protocols/bett.c @@ -169,6 +169,7 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Deserialize error"); break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/bin_raw.c b/lib/subghz/protocols/bin_raw.c index ca52cdd49..9ac339d79 100644 --- a/lib/subghz/protocols/bin_raw.c +++ b/lib/subghz/protocols/bin_raw.c @@ -142,7 +142,7 @@ void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_bin_raw; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = BIN_RAW_BUF_DATA_SIZE * 5; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->data = malloc(instance->encoder.size_upload * sizeof(uint8_t)); @@ -309,6 +309,7 @@ SubGhzProtocolStatus res = SubGhzProtocolStatusErrorParserOthers; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 2762a2484..7be07a476 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -90,7 +90,7 @@ void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_came; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -181,6 +181,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorValueBitCount; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index f8ec7baa0..748d15af5 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -89,7 +89,7 @@ void* subghz_protocol_encoder_came_atomo_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_came_atomo; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 1; instance->encoder.size_upload = 900; //actual size 766+ instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 3bb909dc8..1eb28d94f 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -109,7 +109,7 @@ void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_came_twee; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 1; instance->encoder.size_upload = 1536; //max upload 92*14 = 1288 !!!! instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -254,6 +254,7 @@ SubGhzProtocolStatus if(res != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index fda224bb6..61ef7747b 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -223,6 +223,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorValueBitCount; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/clemsa.c b/lib/subghz/protocols/clemsa.c index 672abcba3..3d3ebe3d9 100644 --- a/lib/subghz/protocols/clemsa.c +++ b/lib/subghz/protocols/clemsa.c @@ -168,6 +168,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/dickert_mahs.c b/lib/subghz/protocols/dickert_mahs.c index 65be6fd0c..f5d710c79 100644 --- a/lib/subghz/protocols/dickert_mahs.c +++ b/lib/subghz/protocols/dickert_mahs.c @@ -132,7 +132,7 @@ void* subghz_protocol_encoder_dickert_mahs_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_dickert_mahs; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -207,6 +207,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorValueBitCount; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c index 7c7946042..158f53169 100644 --- a/lib/subghz/protocols/doitrand.c +++ b/lib/subghz/protocols/doitrand.c @@ -82,7 +82,7 @@ void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_doitrand; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -149,6 +149,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/dooya.c b/lib/subghz/protocols/dooya.c index fd8645a0b..b290da8e1 100644 --- a/lib/subghz/protocols/dooya.c +++ b/lib/subghz/protocols/dooya.c @@ -77,7 +77,7 @@ void* subghz_protocol_encoder_dooya_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_dooya; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -159,6 +159,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/elplast.c b/lib/subghz/protocols/elplast.c index 18d6d07b4..f95c937db 100644 --- a/lib/subghz/protocols/elplast.c +++ b/lib/subghz/protocols/elplast.c @@ -73,7 +73,7 @@ void* subghz_protocol_encoder_elplast_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_elplast; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -141,6 +141,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 147e452eb..03e61d6f2 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -109,7 +109,7 @@ void* subghz_protocol_encoder_faac_slh_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/feron.c b/lib/subghz/protocols/feron.c index 9591a4ebb..d02258f04 100644 --- a/lib/subghz/protocols/feron.c +++ b/lib/subghz/protocols/feron.c @@ -74,7 +74,7 @@ void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_feron; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -160,6 +160,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c index 6b5542410..0cdb442d5 100644 --- a/lib/subghz/protocols/gangqi.c +++ b/lib/subghz/protocols/gangqi.c @@ -76,7 +76,7 @@ void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_gangqi; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -253,6 +253,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 608567626..8572edd58 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -142,6 +142,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/hay21.c b/lib/subghz/protocols/hay21.c index ba6119dae..701e98659 100644 --- a/lib/subghz/protocols/hay21.c +++ b/lib/subghz/protocols/hay21.c @@ -75,7 +75,7 @@ void* subghz_protocol_encoder_hay21_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_hay21; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -267,6 +267,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/hollarm.c b/lib/subghz/protocols/hollarm.c index 9b2a53a05..da0dc97e1 100644 --- a/lib/subghz/protocols/hollarm.c +++ b/lib/subghz/protocols/hollarm.c @@ -76,7 +76,7 @@ void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_hollarm; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -254,6 +254,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index 7ed5fc152..4afe25070 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -86,7 +86,7 @@ void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_holtek; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -155,6 +155,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/holtek_ht12x.c b/lib/subghz/protocols/holtek_ht12x.c index bf5e48adf..595237a1f 100644 --- a/lib/subghz/protocols/holtek_ht12x.c +++ b/lib/subghz/protocols/holtek_ht12x.c @@ -94,7 +94,7 @@ void* subghz_protocol_encoder_holtek_th12x_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_holtek_th12x; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -170,6 +170,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorParserTe; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/honeywell.c b/lib/subghz/protocols/honeywell.c index 1e3f231e8..d8ce0d8eb 100644 --- a/lib/subghz/protocols/honeywell.c +++ b/lib/subghz/protocols/honeywell.c @@ -98,7 +98,7 @@ void* subghz_protocol_encoder_honeywell_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_honeywell; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 4; + instance->encoder.repeat = 5; instance->encoder.size_upload = 64 * 2 + 10; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 0b8f63a24..96f5f5e7f 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -88,7 +88,7 @@ void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment instance->base.protocol = &subghz_protocol_honeywell_wdb; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -156,6 +156,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_honeywell_wdb_deserialize( if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index f74a29fec..250ab4f62 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -80,7 +80,7 @@ void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_hormann; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 2048; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -110,7 +110,7 @@ static bool subghz_protocol_encoder_hormann_get_upload(SubGhzProtocolEncoderHorm } else { instance->encoder.size_upload = size_upload; } - instance->encoder.repeat = 10; //original remote does 10 repeats + instance->encoder.repeat = 3; //original remote does 10 repeats for(size_t repeat = 0; repeat < 20; repeat++) { //Send start bit @@ -153,6 +153,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index 71513051b..7b9bfbf1a 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -86,7 +86,7 @@ void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environmen instance->base.protocol = &subghz_protocol_intertechno_v3; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -176,6 +176,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize( ret = SubGhzProtocolStatusErrorValueBitCount; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/jarolift.c b/lib/subghz/protocols/jarolift.c index 9881b9892..81eca4fde 100644 --- a/lib/subghz/protocols/jarolift.c +++ b/lib/subghz/protocols/jarolift.c @@ -100,7 +100,7 @@ void* subghz_protocol_encoder_jarolift_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index cd657f23f..d5a8a9aa7 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -107,7 +107,7 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - instance->encoder.repeat = 100; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/kinggates_stylo_4k.c b/lib/subghz/protocols/kinggates_stylo_4k.c index 9d7313559..6b8d0e428 100644 --- a/lib/subghz/protocols/kinggates_stylo_4k.c +++ b/lib/subghz/protocols/kinggates_stylo_4k.c @@ -101,7 +101,7 @@ void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* enviro instance->generic.protocol_name = instance->base.protocol->name; instance->keystore = subghz_environment_get_keystore(environment); - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/legrand.c b/lib/subghz/protocols/legrand.c index 94a45694c..7b8b70204 100644 --- a/lib/subghz/protocols/legrand.c +++ b/lib/subghz/protocols/legrand.c @@ -155,6 +155,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorParserTe; break; } + // optional parameter flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c index f024316e9..61a21ec05 100644 --- a/lib/subghz/protocols/linear.c +++ b/lib/subghz/protocols/linear.c @@ -160,6 +160,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/linear_delta3.c b/lib/subghz/protocols/linear_delta3.c index c2f527ba8..515fc43a6 100644 --- a/lib/subghz/protocols/linear_delta3.c +++ b/lib/subghz/protocols/linear_delta3.c @@ -164,6 +164,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_linear_delta3_deserialize( if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/magellan.c b/lib/subghz/protocols/magellan.c index 55048ca61..5fc003ab4 100644 --- a/lib/subghz/protocols/magellan.c +++ b/lib/subghz/protocols/magellan.c @@ -78,7 +78,7 @@ void* subghz_protocol_encoder_magellan_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_magellan; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -164,6 +164,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index 53e4d6895..d70c4eed2 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -77,7 +77,7 @@ void* subghz_protocol_encoder_marantec_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_marantec; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -213,6 +213,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c index 6f636e8ab..fbd16ecbb 100644 --- a/lib/subghz/protocols/marantec24.c +++ b/lib/subghz/protocols/marantec24.c @@ -73,7 +73,7 @@ void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_marantec24; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -155,6 +155,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/mastercode.c b/lib/subghz/protocols/mastercode.c index e4fae40b3..b0b7f789d 100644 --- a/lib/subghz/protocols/mastercode.c +++ b/lib/subghz/protocols/mastercode.c @@ -168,6 +168,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 2c4bf10a3..22e57c364 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -188,6 +188,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index da5497feb..d5c284693 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -77,7 +77,7 @@ void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_nero_radio; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -180,6 +180,7 @@ SubGhzProtocolStatus break; } } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 64a75cfc0..02682f4f1 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -76,7 +76,7 @@ void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_nero_sketch; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -161,6 +161,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index 2e5fa96b5..b47de0079 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -147,6 +147,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorValueBitCount; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 9085ee431..67755c79f 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -104,7 +104,7 @@ void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment) FURI_LOG_D( TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name); } - instance->encoder.repeat = 10; + instance->encoder.repeat = 1; instance->encoder.size_upload = 2400; //wrong!! upload 186*16 = 2976 - actual size about 1728 instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -282,6 +282,7 @@ SubGhzProtocolStatus // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + // flipper_format_read_uint32( // flipper_format, "Data", (uint32_t*)&instance->generic.data_2, 1); if(!flipper_format_rewind(flipper_format)) { diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index 1f2731f54..9b97137f9 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -77,7 +77,7 @@ void* subghz_protocol_encoder_phoenix_v2_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_phoenix_v2; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -322,6 +322,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index 6449f720a..1e8f7098c 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -85,7 +85,7 @@ void* subghz_protocol_encoder_power_smart_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_power_smart; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 1024; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -206,6 +206,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c index 941ff5c56..5e4ca97e8 100644 --- a/lib/subghz/protocols/revers_rb2.c +++ b/lib/subghz/protocols/revers_rb2.c @@ -78,7 +78,7 @@ void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_revers_rb2; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -176,6 +176,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/roger.c b/lib/subghz/protocols/roger.c index 9c33b11ec..62178981c 100644 --- a/lib/subghz/protocols/roger.c +++ b/lib/subghz/protocols/roger.c @@ -76,7 +76,7 @@ void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_roger; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -265,6 +265,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 13af0d302..3d820b318 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -98,7 +98,7 @@ void* subghz_protocol_encoder_secplus_v1_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_secplus_v1; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -298,6 +298,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index ad343968b..902422148 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -92,7 +92,7 @@ void* subghz_protocol_encoder_secplus_v2_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_secplus_v2; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -574,9 +574,11 @@ SubGhzProtocolStatus subghz_protocol_secplus_v2_remote_controller( &instance->generic, instance->secplus_packet_1); subghz_protocol_secplus_v2_encode(instance); + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + subghz_protocol_encoder_secplus_v2_get_upload(instance); //update data diff --git a/lib/subghz/protocols/smc5326.c b/lib/subghz/protocols/smc5326.c index 217dbb780..201fcd9d7 100644 --- a/lib/subghz/protocols/smc5326.c +++ b/lib/subghz/protocols/smc5326.c @@ -101,7 +101,7 @@ void* subghz_protocol_encoder_smc5326_alloc(SubGhzEnvironment* environment) { instance->base.protocol = &subghz_protocol_smc5326; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 5; instance->encoder.size_upload = 128; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -178,6 +178,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorParserTe; break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index c9f6f47bd..04dba4736 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -81,7 +81,7 @@ void* subghz_protocol_encoder_somfy_keytis_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_somfy_keytis; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 2be378b7d..4d4b128f1 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -82,7 +82,7 @@ void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_somfy_telis; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 512; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; diff --git a/lib/subghz/protocols/treadmill37.c b/lib/subghz/protocols/treadmill37.c index e9915c296..8a7badb94 100644 --- a/lib/subghz/protocols/treadmill37.c +++ b/lib/subghz/protocols/treadmill37.c @@ -73,7 +73,7 @@ void* subghz_protocol_encoder_treadmill37_alloc(SubGhzEnvironment* environment) instance->base.protocol = &subghz_protocol_treadmill37; instance->generic.protocol_name = instance->base.protocol->name; - instance->encoder.repeat = 10; + instance->encoder.repeat = 3; instance->encoder.size_upload = 256; instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); instance->encoder.is_running = false; @@ -151,6 +151,7 @@ SubGhzProtocolStatus if(ret != SubGhzProtocolStatusOk) { break; } + // Optional value flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); diff --git a/targets/f7/furi_hal/furi_hal_subghz.c b/targets/f7/furi_hal/furi_hal_subghz.c index dc6add277..ece8dde2c 100644 --- a/targets/f7/furi_hal/furi_hal_subghz.c +++ b/targets/f7/furi_hal/furi_hal_subghz.c @@ -684,6 +684,8 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { while(samples > 0) { volatile uint32_t duration = furi_hal_subghz_async_tx_middleware_get_duration( &furi_hal_subghz_async_tx.middleware, furi_hal_subghz_async_tx.callback); + // if duration == 0 then we stop DMA interrupt(that used to refill buffer) and write to buffer 0 as last element. + // later DMA write this 0 to ARR and timer TIM2 will be stopped. if(duration == 0) { *buffer = 0; buffer++; @@ -756,48 +758,64 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_async_tx.buffer = malloc(FURI_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - // Connect CC1101_GD0 to TIM2 as output + // Here we use TIM2_CH2 (Timer 2 Channel 2) to generate HI/LOW signals for C1101 with current durations. + // DMA update/rewrite TIM2 settings (ARR) with new duration each time TIM2 completes. + // Every time when timer counter exeed current TIM2-ARR (AutoReload Register) value timer generate event that call DMA + // DMA load next new value from buffer to TIM2-ARR and timer start count up from 0 to new value again + // Totally we have timer that generate events and update they settings with new durations by DMA action. + // When duration = 0 then DMA wirte 0 to ARR. So when we set ARR=0 - thats mean TIM2 stop counting. + + // Connect CC1101_GD0 to TIM2 as output (Pin B3 - GpioAltFn1TIM2 - TIM2, CH2) furi_hal_gpio_init_ex( &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); - // Configure DMA - LL_DMA_InitTypeDef dma_config = {0}; - 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; - dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - dma_config.NbData = FURI_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL; - dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; + // Configure DMA to update TIM2->ARR + LL_DMA_InitTypeDef dma_config = {0}; // DMA settings structure + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->ARR); // DMA destination TIM2->ARR + dma_config.MemoryOrM2MDstAddress = + (uint32_t)furi_hal_subghz_async_tx.buffer; // DMA buffer with signals durations + dma_config.Direction = + LL_DMA_DIRECTION_MEMORY_TO_PERIPH; // DMA direction from memory to periperhal + dma_config.Mode = LL_DMA_MODE_CIRCULAR; // DMA mode + dma_config.PeriphOrM2MSrcIncMode = + LL_DMA_PERIPH_NOINCREMENT; // DMA destination not changed - allways stay on ARR (AutoReload Register) + dma_config.MemoryOrM2MDstIncMode = + LL_DMA_MEMORY_INCREMENT; // DMA source increment - step by step on durations buffer + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; // DMA source packet size + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; // DMA destination packet size + dma_config.NbData = FURI_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL; // DMA buffer size + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; // DMA start by TIM2 event dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; // Ensure that ARR is updated before anyone else try to check it - LL_DMA_Init(SUBGHZ_DMA_CH1_DEF, &dma_config); + LL_DMA_Init(SUBGHZ_DMA_CH1_DEF, &dma_config); // Setup DMA with settings structure + // setup interrupt for DMA. When DMA generate interrupt event we call furi_hal_subghz_async_tx_dma_isr furi_hal_interrupt_set_isr(SUBGHZ_DMA_CH1_IRQ, furi_hal_subghz_async_tx_dma_isr, NULL); - LL_DMA_EnableIT_TC(SUBGHZ_DMA_CH1_DEF); - LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF); - LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF); + LL_DMA_EnableIT_TC(SUBGHZ_DMA_CH1_DEF); // interrupt for full buffer sent + LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF); // interrupt for half buffer sent + LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF); // Enable - furi_hal_bus_enable(FuriHalBusTIM2); + furi_hal_bus_enable(FuriHalBusTIM2); // Enable TIM2 // Configure TIM2 - LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); + LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); // TIM2 set counter mode UP + // Set the division ratio between the timer clock and the sampling clock 1:1 LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); + LL_TIM_SetPrescaler(TIM2, 64 - 1); // Perscaler 64 Mghz/64 = 1 Mghz (1 000 000 tick/sec) + // AutoReload Register (ARR) 1000 ticks = 1/1000 Mghz = 1 millisecond, will be changed by DMA by new durations LL_TIM_SetAutoReload(TIM2, 1000); - LL_TIM_SetPrescaler(TIM2, 64 - 1); - LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); - LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); // ClockSource for TIM2 + LL_TIM_DisableARRPreload( + TIM2); // Change TIM2 setting immediately (dont wait when counter will be overload) // Configure TIM2 CH2 - LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; //Settings structure + // CH2 working mode - TOGGLE (swith between HI and LOW levels) TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_TOGGLE; TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; - TIM_OC_InitStruct.CompareValue = 0; - TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; - LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + TIM_OC_InitStruct.CompareValue = 0; // Counter value to generate events and TOGGLE output + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; // Initial CH2 state - HIGH level + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); // Apply settings to CH2 LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); LL_TIM_DisableMasterSlaveMode(TIM2); @@ -805,8 +823,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_async_tx_refill( furi_hal_subghz_async_tx.buffer, FURI_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); - LL_TIM_EnableDMAReq_UPDATE(TIM2); - LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_EnableDMAReq_UPDATE(TIM2); // Setup calling DMA by TIM2 events + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); //Enable TIM2 CH2 // Start debug if(furi_hal_subghz_start_debug()) { @@ -841,8 +859,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* #endif furi_hal_subghz_tx(); - LL_TIM_SetCounter(TIM2, 0); - LL_TIM_EnableCounter(TIM2); + LL_TIM_SetCounter(TIM2, 0); // Reset TIM2 + LL_TIM_EnableCounter(TIM2); // Start TIM2 counting. return true; }