[FL-3093, FL-3087] SubGhz: Fix Raw write, add short duration filter setting (#2300)
* SubGhz: Fix recording RAW files, sometimes could not start at a high level * SubGhz: subghz_worker, add short duration filter setting * SubGhz: capture raw timings in cli. Furi: clear pending interrupts on ISR set/reset * SubGhz: fix start duration in furi_hal_subghz_start_async_rx * [FL-3093] SubGhz: hopping issue in some regions * [FL-3087] SubGhz: fix delete-ok issue * SubGhz: remove copypasta from rx_raw cli command Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									cee9b640b3
								
							
						
					
					
						commit
						99253a0e28
					
				| @ -28,13 +28,8 @@ bool subghz_scene_delete_success_on_event(void* context, SceneManagerEvent event | |||||||
|         if(event.event == SubGhzCustomEventSceneDeleteSuccess) { |         if(event.event == SubGhzCustomEventSceneDeleteSuccess) { | ||||||
|             if(scene_manager_search_and_switch_to_previous_scene( |             if(scene_manager_search_and_switch_to_previous_scene( | ||||||
|                    subghz->scene_manager, SubGhzSceneReadRAW)) { |                    subghz->scene_manager, SubGhzSceneReadRAW)) { | ||||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); |  | ||||||
|             } else if(scene_manager_search_and_switch_to_previous_scene( |             } else if(scene_manager_search_and_switch_to_previous_scene( | ||||||
|                           subghz->scene_manager, SubGhzSceneSaved)) { |                           subghz->scene_manager, SubGhzSceneSaved)) { | ||||||
|                 // Commented so that the user doesn't have to press
 |  | ||||||
|                 // back twice to get to the main SubGhz menu after
 |  | ||||||
|                 // deleting a file.
 |  | ||||||
|                 //scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved);
 |  | ||||||
|             } else { |             } else { | ||||||
|                 scene_manager_search_and_switch_to_previous_scene( |                 scene_manager_search_and_switch_to_previous_scene( | ||||||
|                     subghz->scene_manager, SubGhzSceneStart); |                     subghz->scene_manager, SubGhzSceneStart); | ||||||
|  | |||||||
| @ -129,6 +129,21 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) | |||||||
|                        subghz_history_get_raw_data( |                        subghz_history_get_raw_data( | ||||||
|                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) { |                            subghz->txrx->history, subghz->txrx->idx_menu_chosen))) { | ||||||
|                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); |                     scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); | ||||||
|  |                     if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { | ||||||
|  |                         subghz_tx_stop(subghz); | ||||||
|  |                     } | ||||||
|  |                     if(subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) { | ||||||
|  |                         subghz_begin( | ||||||
|  |                             subghz, | ||||||
|  |                             subghz_setting_get_preset_data_by_name( | ||||||
|  |                                 subghz->setting, | ||||||
|  |                                 furi_string_get_cstr(subghz->txrx->preset->name))); | ||||||
|  |                         subghz_rx(subghz, subghz->txrx->preset->frequency); | ||||||
|  |                     } | ||||||
|  |                     if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { | ||||||
|  |                         subghz->txrx->hopper_state = SubGhzHopperStateRunnig; | ||||||
|  |                     } | ||||||
|  |                     subghz->state_notifications = SubGhzNotificationStateRx; | ||||||
|                 } else { |                 } else { | ||||||
|                     subghz->state_notifications = SubGhzNotificationStateTx; |                     subghz->state_notifications = SubGhzNotificationStateTx; | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -309,6 +309,81 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { | |||||||
|     free(instance); |     free(instance); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void subghz_cli_command_rx_raw(Cli* cli, FuriString* args, void* context) { | ||||||
|  |     UNUSED(context); | ||||||
|  |     uint32_t frequency = 433920000; | ||||||
|  | 
 | ||||||
|  |     if(furi_string_size(args)) { | ||||||
|  |         int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); | ||||||
|  |         if(ret != 1) { | ||||||
|  |             printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); | ||||||
|  |             cli_print_usage("subghz rx", "<Frequency: in Hz>", furi_string_get_cstr(args)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if(!furi_hal_subghz_is_frequency_valid(frequency)) { | ||||||
|  |             printf( | ||||||
|  |                 "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", | ||||||
|  |                 frequency); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Allocate context and buffers
 | ||||||
|  |     SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); | ||||||
|  |     instance->stream = | ||||||
|  |         furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); | ||||||
|  |     furi_check(instance->stream); | ||||||
|  | 
 | ||||||
|  |     // Configure radio
 | ||||||
|  |     furi_hal_subghz_reset(); | ||||||
|  |     furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok270Async); | ||||||
|  |     frequency = furi_hal_subghz_set_frequency_and_path(frequency); | ||||||
|  |     furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); | ||||||
|  | 
 | ||||||
|  |     furi_hal_power_suppress_charge_enter(); | ||||||
|  | 
 | ||||||
|  |     // Prepare and start RX
 | ||||||
|  |     furi_hal_subghz_start_async_rx(subghz_cli_command_rx_capture_callback, instance); | ||||||
|  | 
 | ||||||
|  |     // Wait for packets to arrive
 | ||||||
|  |     printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); | ||||||
|  |     LevelDuration level_duration; | ||||||
|  |     size_t counter = 0; | ||||||
|  |     while(!cli_cmd_interrupt_received(cli)) { | ||||||
|  |         int ret = furi_stream_buffer_receive( | ||||||
|  |             instance->stream, &level_duration, sizeof(LevelDuration), 10); | ||||||
|  |         if(ret == 0) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         if(ret != sizeof(LevelDuration)) { | ||||||
|  |             puts("stream corrupt"); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         if(level_duration_is_reset(level_duration)) { | ||||||
|  |             puts(". "); | ||||||
|  |         } else { | ||||||
|  |             bool level = level_duration_get_level(level_duration); | ||||||
|  |             uint32_t duration = level_duration_get_duration(level_duration); | ||||||
|  |             printf("%c%lu ", level ? '+' : '-', duration); | ||||||
|  |         } | ||||||
|  |         furi_thread_stdout_flush(); | ||||||
|  |         counter++; | ||||||
|  |         if(counter > 255) { | ||||||
|  |             puts("\r\n"); | ||||||
|  |             counter = 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Shutdown radio
 | ||||||
|  |     furi_hal_subghz_stop_async_rx(); | ||||||
|  |     furi_hal_subghz_sleep(); | ||||||
|  | 
 | ||||||
|  |     furi_hal_power_suppress_charge_exit(); | ||||||
|  | 
 | ||||||
|  |     // Cleanup
 | ||||||
|  |     furi_stream_buffer_free(instance->stream); | ||||||
|  |     free(instance); | ||||||
|  | } | ||||||
| void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) { | void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) { | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     FuriString* file_name; |     FuriString* file_name; | ||||||
| @ -431,7 +506,8 @@ static void subghz_cli_command_print_usage() { | |||||||
|     printf("\tchat <frequency:in Hz>\t - Chat with other Flippers\r\n"); |     printf("\tchat <frequency:in Hz>\t - Chat with other Flippers\r\n"); | ||||||
|     printf( |     printf( | ||||||
|         "\ttx <3 byte Key: in hex> <frequency: in Hz> <te: us> <repeat: count>\t - Transmitting key\r\n"); |         "\ttx <3 byte Key: in hex> <frequency: in Hz> <te: us> <repeat: count>\t - Transmitting key\r\n"); | ||||||
|     printf("\trx <frequency:in Hz>\t - Reception key\r\n"); |     printf("\trx <frequency:in Hz>\t - Receive\r\n"); | ||||||
|  |     printf("\trx_raw <frequency:in Hz>\t - Receive RAW\r\n"); | ||||||
|     printf("\tdecode_raw <file_name: path_RAW_file>\t - Testing\r\n"); |     printf("\tdecode_raw <file_name: path_RAW_file>\t - Testing\r\n"); | ||||||
| 
 | 
 | ||||||
|     if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { |     if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { | ||||||
| @ -733,6 +809,11 @@ static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if(furi_string_cmp_str(cmd, "rx_raw") == 0) { | ||||||
|  |             subghz_cli_command_rx_raw(cli, args, context); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if(furi_string_cmp_str(cmd, "decode_raw") == 0) { |         if(furi_string_cmp_str(cmd, "decode_raw") == 0) { | ||||||
|             subghz_cli_command_decode_raw(cli, args, context); |             subghz_cli_command_decode_raw(cli, args, context); | ||||||
|             break; |             break; | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| entry,status,name,type,params | entry,status,name,type,params | ||||||
| Version,+,13.0,, | Version,+,13.1,, | ||||||
| Header,+,applications/services/bt/bt_service/bt.h,, | Header,+,applications/services/bt/bt_service/bt.h,, | ||||||
| Header,+,applications/services/cli/cli.h,, | Header,+,applications/services/cli/cli.h,, | ||||||
| Header,+,applications/services/cli/cli_vcp.h,, | Header,+,applications/services/cli/cli_vcp.h,, | ||||||
| @ -2675,6 +2675,7 @@ Function,+,subghz_worker_free,void,SubGhzWorker* | |||||||
| Function,+,subghz_worker_is_running,_Bool,SubGhzWorker* | Function,+,subghz_worker_is_running,_Bool,SubGhzWorker* | ||||||
| Function,+,subghz_worker_rx_callback,void,"_Bool, uint32_t, void*" | Function,+,subghz_worker_rx_callback,void,"_Bool, uint32_t, void*" | ||||||
| Function,+,subghz_worker_set_context,void,"SubGhzWorker*, void*" | Function,+,subghz_worker_set_context,void,"SubGhzWorker*, void*" | ||||||
|  | Function,+,subghz_worker_set_filter,void,"SubGhzWorker*, uint16_t" | ||||||
| Function,+,subghz_worker_set_overrun_callback,void,"SubGhzWorker*, SubGhzWorkerOverrunCallback" | Function,+,subghz_worker_set_overrun_callback,void,"SubGhzWorker*, SubGhzWorkerOverrunCallback" | ||||||
| Function,+,subghz_worker_set_pair_callback,void,"SubGhzWorker*, SubGhzWorkerPairCallback" | Function,+,subghz_worker_set_pair_callback,void,"SubGhzWorker*, SubGhzWorkerPairCallback" | ||||||
| Function,+,subghz_worker_start,void,SubGhzWorker* | Function,+,subghz_worker_start,void,SubGhzWorker* | ||||||
|  | |||||||
| 
 | 
| @ -74,6 +74,21 @@ __attribute__((always_inline)) static inline void | |||||||
|     NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]); |     NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__((always_inline)) static inline void | ||||||
|  |     furi_hal_interrupt_clear_pending(FuriHalInterruptId index) { | ||||||
|  |     NVIC_ClearPendingIRQ(furi_hal_interrupt_irqn[index]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__((always_inline)) static inline void | ||||||
|  |     furi_hal_interrupt_get_pending(FuriHalInterruptId index) { | ||||||
|  |     NVIC_GetPendingIRQ(furi_hal_interrupt_irqn[index]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__((always_inline)) static inline void | ||||||
|  |     furi_hal_interrupt_set_pending(FuriHalInterruptId index) { | ||||||
|  |     NVIC_SetPendingIRQ(furi_hal_interrupt_irqn[index]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| __attribute__((always_inline)) static inline void | __attribute__((always_inline)) static inline void | ||||||
|     furi_hal_interrupt_disable(FuriHalInterruptId index) { |     furi_hal_interrupt_disable(FuriHalInterruptId index) { | ||||||
|     NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]); |     NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]); | ||||||
| @ -123,6 +138,7 @@ void furi_hal_interrupt_set_isr_ex( | |||||||
|         // Pre ISR clear
 |         // Pre ISR clear
 | ||||||
|         furi_assert(furi_hal_interrupt_isr[index].isr != NULL); |         furi_assert(furi_hal_interrupt_isr[index].isr != NULL); | ||||||
|         furi_hal_interrupt_disable(index); |         furi_hal_interrupt_disable(index); | ||||||
|  |         furi_hal_interrupt_clear_pending(index); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_hal_interrupt_isr[index].isr = isr; |     furi_hal_interrupt_isr[index].isr = isr; | ||||||
| @ -131,6 +147,7 @@ void furi_hal_interrupt_set_isr_ex( | |||||||
| 
 | 
 | ||||||
|     if(isr) { |     if(isr) { | ||||||
|         // Post ISR set
 |         // Post ISR set
 | ||||||
|  |         furi_hal_interrupt_clear_pending(index); | ||||||
|         furi_hal_interrupt_enable(index, priority); |         furi_hal_interrupt_enable(index, priority); | ||||||
|     } else { |     } else { | ||||||
|         // Post ISR clear
 |         // Post ISR clear
 | ||||||
|  | |||||||
| @ -438,7 +438,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* | |||||||
|     TIM_InitStruct.Prescaler = 64 - 1; |     TIM_InitStruct.Prescaler = 64 - 1; | ||||||
|     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; |     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; | ||||||
|     TIM_InitStruct.Autoreload = 0x7FFFFFFE; |     TIM_InitStruct.Autoreload = 0x7FFFFFFE; | ||||||
|     TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; |     TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; // Clock division for capture filter
 | ||||||
|     LL_TIM_Init(TIM2, &TIM_InitStruct); |     LL_TIM_Init(TIM2, &TIM_InitStruct); | ||||||
| 
 | 
 | ||||||
|     // Timer: advanced
 |     // Timer: advanced
 | ||||||
| @ -455,13 +455,15 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* | |||||||
|     LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI); |     LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI); | ||||||
|     LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); |     LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); | ||||||
|     LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING); |     LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING); | ||||||
|     LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); |  | ||||||
| 
 | 
 | ||||||
|     // Timer: channel 2 direct
 |     // Timer: channel 2 direct
 | ||||||
|     LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); |     LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); | ||||||
|     LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); |     LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); | ||||||
|     LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); |     LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); | ||||||
|     LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); |     LL_TIM_IC_SetFilter( | ||||||
|  |         TIM2, | ||||||
|  |         LL_TIM_CHANNEL_CH2, | ||||||
|  |         LL_TIM_IC_FILTER_FDIV32_N8); // Capture filter: 1/(64000000/64/4/32*8) = 16us
 | ||||||
| 
 | 
 | ||||||
|     // ISR setup
 |     // ISR setup
 | ||||||
|     furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL); |     furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL); | ||||||
| @ -481,6 +483,9 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* | |||||||
| 
 | 
 | ||||||
|     // Switch to RX
 |     // Switch to RX
 | ||||||
|     furi_hal_subghz_rx(); |     furi_hal_subghz_rx(); | ||||||
|  | 
 | ||||||
|  |     //Clear the variable after the end of the session
 | ||||||
|  |     furi_hal_subghz_capture_delta_duration = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_subghz_stop_async_rx() { | void furi_hal_subghz_stop_async_rx() { | ||||||
|  | |||||||
| @ -159,6 +159,7 @@ bool subghz_protocol_raw_save_to_file_init( | |||||||
|         instance->upload_raw = malloc(SUBGHZ_DOWNLOAD_MAX_SIZE * sizeof(int32_t)); |         instance->upload_raw = malloc(SUBGHZ_DOWNLOAD_MAX_SIZE * sizeof(int32_t)); | ||||||
|         instance->file_is_open = RAWFileIsOpenWrite; |         instance->file_is_open = RAWFileIsOpenWrite; | ||||||
|         instance->sample_write = 0; |         instance->sample_write = 0; | ||||||
|  |         instance->last_level = false; | ||||||
|         instance->pause = false; |         instance->pause = false; | ||||||
|         init = true; |         init = true; | ||||||
|     } while(0); |     } while(0); | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ struct SubGhzWorker { | |||||||
|     volatile bool overrun; |     volatile bool overrun; | ||||||
| 
 | 
 | ||||||
|     LevelDuration filter_level_duration; |     LevelDuration filter_level_duration; | ||||||
|     bool filter_running; |  | ||||||
|     uint16_t filter_duration; |     uint16_t filter_duration; | ||||||
| 
 | 
 | ||||||
|     SubGhzWorkerOverrunCallback overrun_callback; |     SubGhzWorkerOverrunCallback overrun_callback; | ||||||
| @ -59,7 +58,6 @@ static int32_t subghz_worker_thread_callback(void* context) { | |||||||
|                 bool level = level_duration_get_level(level_duration); |                 bool level = level_duration_get_level(level_duration); | ||||||
|                 uint32_t duration = level_duration_get_duration(level_duration); |                 uint32_t duration = level_duration_get_duration(level_duration); | ||||||
| 
 | 
 | ||||||
|                 if(instance->filter_running) { |  | ||||||
|                 if((duration < instance->filter_duration) || |                 if((duration < instance->filter_duration) || | ||||||
|                    (instance->filter_level_duration.level == level)) { |                    (instance->filter_level_duration.level == level)) { | ||||||
|                     instance->filter_level_duration.duration += duration; |                     instance->filter_level_duration.duration += duration; | ||||||
| @ -74,10 +72,6 @@ static int32_t subghz_worker_thread_callback(void* context) { | |||||||
|                     instance->filter_level_duration.duration = duration; |                     instance->filter_level_duration.duration = duration; | ||||||
|                     instance->filter_level_duration.level = level; |                     instance->filter_level_duration.level = level; | ||||||
|                 } |                 } | ||||||
|                 } else { |  | ||||||
|                     if(instance->pair_callback) |  | ||||||
|                         instance->pair_callback(instance->context, level, duration); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -94,8 +88,7 @@ SubGhzWorker* subghz_worker_alloc() { | |||||||
|     instance->stream = |     instance->stream = | ||||||
|         furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); |         furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); | ||||||
| 
 | 
 | ||||||
|     //setting filter
 |     //setting default filter in us
 | ||||||
|     instance->filter_running = true; |  | ||||||
|     instance->filter_duration = 30; |     instance->filter_duration = 30; | ||||||
| 
 | 
 | ||||||
|     return instance; |     return instance; | ||||||
| @ -149,3 +142,8 @@ bool subghz_worker_is_running(SubGhzWorker* instance) { | |||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|     return instance->running; |     return instance->running; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout) { | ||||||
|  |     furi_assert(instance); | ||||||
|  |     instance->filter_duration = timeout; | ||||||
|  | } | ||||||
| @ -67,6 +67,14 @@ void subghz_worker_stop(SubGhzWorker* instance); | |||||||
|  */ |  */ | ||||||
| bool subghz_worker_is_running(SubGhzWorker* instance); | bool subghz_worker_is_running(SubGhzWorker* instance); | ||||||
| 
 | 
 | ||||||
|  | /** 
 | ||||||
|  |  * Short duration filter setting. | ||||||
|  |  * glues short durations into 1. The default setting is 30 us, if set to 0 the filter will be disabled | ||||||
|  |  * @param instance Pointer to a SubGhzWorker instance | ||||||
|  |  * @param timeout time in us | ||||||
|  |  */ | ||||||
|  | void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm