From b53924c27ab00dd584456efe3268060e142c1ae7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 26 Feb 2023 05:23:26 +0300 Subject: [PATCH] Infrared debug settings - output pin --- applications/main/infrared/infrared.c | 9 ++ applications/main/infrared/infrared_i.h | 3 + .../infrared/scenes/infrared_scene_config.h | 1 + .../scenes/infrared_scene_debug_settings.c | 59 ++++++++++++ .../infrared/scenes/infrared_scene_start.c | 18 +++- firmware/targets/f7/api_symbols.csv | 2 + .../targets/f7/furi_hal/furi_hal_infrared.c | 90 +++++++++++-------- .../furi_hal_include/furi_hal_infrared.h | 6 ++ 8 files changed, 150 insertions(+), 38 deletions(-) create mode 100644 applications/main/infrared/scenes/infrared_scene_debug_settings.c diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index 9d78a09b6..14729e0d8 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -148,6 +148,12 @@ static Infrared* infrared_alloc() { view_dispatcher_add_view( view_dispatcher, InfraredViewTextInput, text_input_get_view(infrared->text_input)); + infrared->variable_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + infrared->view_dispatcher, + InfraredViewVariableItemList, + variable_item_list_get_view(infrared->variable_item_list)); + infrared->dialog_ex = dialog_ex_alloc(); view_dispatcher_add_view( view_dispatcher, InfraredViewDialogEx, dialog_ex_get_view(infrared->dialog_ex)); @@ -195,6 +201,9 @@ static void infrared_free(Infrared* infrared) { view_dispatcher_remove_view(view_dispatcher, InfraredViewTextInput); text_input_free(infrared->text_input); + view_dispatcher_remove_view(infrared->view_dispatcher, InfraredViewVariableItemList); + variable_item_list_free(infrared->variable_item_list); + view_dispatcher_remove_view(view_dispatcher, InfraredViewDialogEx); dialog_ex_free(infrared->dialog_ex); diff --git a/applications/main/infrared/infrared_i.h b/applications/main/infrared/infrared_i.h index 5b555e4bb..72800d994 100644 --- a/applications/main/infrared/infrared_i.h +++ b/applications/main/infrared/infrared_i.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,7 @@ struct Infrared { Submenu* submenu; TextInput* text_input; + VariableItemList* variable_item_list; DialogEx* dialog_ex; ButtonMenu* button_menu; Popup* popup; @@ -107,6 +109,7 @@ struct Infrared { typedef enum { InfraredViewSubmenu, InfraredViewTextInput, + InfraredViewVariableItemList, InfraredViewDialogEx, InfraredViewButtonMenu, InfraredViewPopup, diff --git a/applications/main/infrared/scenes/infrared_scene_config.h b/applications/main/infrared/scenes/infrared_scene_config.h index 551485295..b15974941 100644 --- a/applications/main/infrared/scenes/infrared_scene_config.h +++ b/applications/main/infrared/scenes/infrared_scene_config.h @@ -21,4 +21,5 @@ ADD_SCENE(infrared, universal_audio, UniversalAudio) ADD_SCENE(infrared, universal_projector, UniversalProjector) ADD_SCENE(infrared, debug, Debug) ADD_SCENE(infrared, error_databases, ErrorDatabases) +ADD_SCENE(infrared, debug_settings, DebugSettings) ADD_SCENE(infrared, rpc, Rpc) diff --git a/applications/main/infrared/scenes/infrared_scene_debug_settings.c b/applications/main/infrared/scenes/infrared_scene_debug_settings.c new file mode 100644 index 000000000..0bc830788 --- /dev/null +++ b/applications/main/infrared/scenes/infrared_scene_debug_settings.c @@ -0,0 +1,59 @@ +#include "../infrared_i.h" +#include + +uint8_t value_index_ir; + +#define DEB_PINS_COUNT (sizeof(infrared_debug_cfg_variables_text) / sizeof(char* const)) +const char* const infrared_debug_cfg_variables_text[] = { + "Internal", + "2 (A7)", +}; + +static void infrared_scene_debug_settings_changed(VariableItem* item) { + Infrared* infrared = variable_item_get_context(item); + value_index_ir = variable_item_get_current_value_index(item); + UNUSED(infrared); + + variable_item_set_current_value_text(item, infrared_debug_cfg_variables_text[value_index_ir]); + + furi_hal_infrared_set_debug_out(value_index_ir); +} +static void infrared_debug_settings_start_var_list_enter_callback(void* context, uint32_t index) { + Infrared* infrared = context; + view_dispatcher_send_custom_event(infrared->view_dispatcher, index); +} + +void infrared_scene_debug_settings_on_enter(void* context) { + Infrared* infrared = context; + + VariableItemList* variable_item_list = infrared->variable_item_list; + + value_index_ir = furi_hal_infrared_get_debug_out_status(); + VariableItem* item = variable_item_list_add( + variable_item_list, + "Send signal to", + DEB_PINS_COUNT, + infrared_scene_debug_settings_changed, + infrared); + + variable_item_list_set_enter_callback( + variable_item_list, infrared_debug_settings_start_var_list_enter_callback, infrared); + + variable_item_set_current_value_index(item, value_index_ir); + variable_item_set_current_value_text(item, infrared_debug_cfg_variables_text[value_index_ir]); + + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewVariableItemList); +} + +bool infrared_scene_debug_settings_on_event(void* context, SceneManagerEvent event) { + Infrared* infrared = context; + UNUSED(infrared); + UNUSED(event); + + return false; +} + +void infrared_scene_debug_settings_on_exit(void* context) { + Infrared* infrared = context; + variable_item_list_reset(infrared->variable_item_list); +} diff --git a/applications/main/infrared/scenes/infrared_scene_start.c b/applications/main/infrared/scenes/infrared_scene_start.c index 28aa384c4..816d57294 100644 --- a/applications/main/infrared/scenes/infrared_scene_start.c +++ b/applications/main/infrared/scenes/infrared_scene_start.c @@ -5,7 +5,8 @@ enum SubmenuIndex { SubmenuIndexLearnNewRemote, SubmenuIndexLearnNewRemoteRaw, SubmenuIndexSavedRemotes, - SubmenuIndexDebug + SubmenuIndexDebug, + SubmenuIndexDebugSettings }; static void infrared_scene_start_submenu_callback(void* context, uint32_t index) { @@ -45,7 +46,17 @@ void infrared_scene_start_on_enter(void* context) { infrared_scene_start_submenu_callback, infrared); submenu_add_item( - submenu, "Debug", SubmenuIndexDebug, infrared_scene_start_submenu_callback, infrared); + submenu, + "Debug RX", + SubmenuIndexDebug, + infrared_scene_start_submenu_callback, + infrared); + submenu_add_item( + submenu, + "Debug Settings", + SubmenuIndexDebugSettings, + infrared_scene_start_submenu_callback, + infrared); } const uint32_t submenu_index = @@ -86,6 +97,9 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { } else if(submenu_index == SubmenuIndexDebug) { scene_manager_next_scene(scene_manager, InfraredSceneDebug); consumed = true; + } else if(submenu_index == SubmenuIndexDebugSettings) { + scene_manager_next_scene(scene_manager, InfraredSceneDebugSettings); + consumed = true; } } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index d0948b9a8..a2f851f28 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1168,7 +1168,9 @@ Function,+,furi_hal_infrared_async_tx_set_signal_sent_isr_callback,void,"FuriHal Function,+,furi_hal_infrared_async_tx_start,void,"uint32_t, float" Function,+,furi_hal_infrared_async_tx_stop,void, Function,+,furi_hal_infrared_async_tx_wait_termination,void, +Function,+,furi_hal_infrared_get_debug_out_status,_Bool, Function,+,furi_hal_infrared_is_busy,_Bool, +Function,+,furi_hal_infrared_set_debug_out,void,_Bool Function,-,furi_hal_init,void, Function,-,furi_hal_init_early,void, Function,-,furi_hal_interrupt_init,void, diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index c1d24f803..b65ea42e1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -13,13 +13,6 @@ #include #include -#define INFRARED_TX_DEBUG 0 - -#if INFRARED_TX_DEBUG == 1 -#define gpio_infrared_tx gpio_infrared_tx_debug -const GpioPin gpio_infrared_tx_debug = {.port = GPIOA, .pin = GPIO_PIN_7}; -#endif - #define INFRARED_TIM_TX_DMA_BUFFER_SIZE 200 #define INFRARED_POLARITY_SHIFT 1 @@ -79,6 +72,7 @@ typedef enum { static volatile InfraredState furi_hal_infrared_state = InfraredStateIdle; static InfraredTimTx infrared_tim_tx; static InfraredTimRx infrared_tim_rx; +static bool infrared_external_output; static void furi_hal_infrared_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift); static void furi_hal_infrared_async_tx_free_resources(void); @@ -89,6 +83,14 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void); static void furi_hal_infrared_tx_dma_polarity_isr(); static void furi_hal_infrared_tx_dma_isr(); +void furi_hal_infrared_set_debug_out(bool enable) { + infrared_external_output = enable; +} + +bool furi_hal_infrared_get_debug_out_status(void) { + return infrared_external_output; +} + static void furi_hal_infrared_tim_rx_isr() { static uint32_t previous_captured_ch2 = 0; @@ -340,25 +342,25 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc LL_TIM_EnableARRPreload(TIM1); LL_TIM_SetAutoReload( TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq)); -#if INFRARED_TX_DEBUG == 1 - LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); - /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); - LL_TIM_DisableIT_CC1(TIM1); -#else - LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); - LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); - /* LL_TIM_OCMODE_PWM2 set by DMA */ - LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); - LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); - LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); - LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N); - LL_TIM_DisableIT_CC3(TIM1); -#endif + if(infrared_external_output) { + LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + /* LL_TIM_OCMODE_PWM2 set by DMA */ + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); + LL_TIM_DisableIT_CC1(TIM1); + } else { + LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); + /* LL_TIM_OCMODE_PWM2 set by DMA */ + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE); + LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N); + LL_TIM_DisableIT_CC3(TIM1); + } LL_TIM_DisableMasterSlaveMode(TIM1); LL_TIM_EnableAllOutputs(TIM1); LL_TIM_DisableIT_UPDATE(TIM1); @@ -370,11 +372,11 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; -#if INFRARED_TX_DEBUG == 1 - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1); -#else - dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2); -#endif + if(infrared_external_output) { + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1); + } else { + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2); + } dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_NORMAL; @@ -567,7 +569,11 @@ static void furi_hal_infrared_async_tx_free_resources(void) { (furi_hal_infrared_state == InfraredStateIdle) || (furi_hal_infrared_state == InfraredStateAsyncTxStopped)); - furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + if(infrared_external_output) { + furi_hal_gpio_init(&gpio_ext_pa7, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + } else { + furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + } furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL); furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL); LL_TIM_DeInit(TIM1); @@ -625,10 +631,22 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { furi_delay_us(5); LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ furi_delay_us(5); - LL_GPIO_ResetOutputPin( - gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */ - furi_hal_gpio_init_ex( - &gpio_infrared_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); + if(infrared_external_output) { + LL_GPIO_ResetOutputPin( + gpio_ext_pa7.port, gpio_ext_pa7.pin); /* when disable it prevents false pulse */ + furi_hal_gpio_init_ex( + &gpio_ext_pa7, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); + } else { + LL_GPIO_ResetOutputPin( + gpio_infrared_tx.port, + gpio_infrared_tx.pin); /* when disable it prevents false pulse */ + furi_hal_gpio_init_ex( + &gpio_infrared_tx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedHigh, + GpioAltFn1TIM1); + } FURI_CRITICAL_ENTER(); LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */ diff --git a/firmware/targets/furi_hal_include/furi_hal_infrared.h b/firmware/targets/furi_hal_include/furi_hal_infrared.h index 5fcea0661..bac3aba1e 100644 --- a/firmware/targets/furi_hal_include/furi_hal_infrared.h +++ b/firmware/targets/furi_hal_include/furi_hal_infrared.h @@ -48,6 +48,12 @@ typedef void (*FuriHalInfraredRxCaptureCallback)(void* ctx, bool level, uint32_t */ typedef void (*FuriHalInfraredRxTimeoutCallback)(void* ctx); +// Debug TX pin set +void furi_hal_infrared_set_debug_out(bool enable); + +// Debug TX pin get status +bool furi_hal_infrared_get_debug_out_status(void); + /** Initialize INFRARED RX timer to receive interrupts. * * It provides interrupts for every RX-signal edge changing with its duration.