#include "bsp/bsp_driver.h" #include "libs/logger.h" static void _io_init(void) { rcu_apb2_periph_clock_enable(ENC_A_RCU); rcu_apb2_periph_clock_enable(ENC_B_RCU); rcu_apb2_periph_clock_enable(ENC_PWM_RCU); rcu_apb2_periph_clock_enable(ENC_I_RCU); #ifdef TIMER2_PB4_PB5_REMAP gpio_pin_remap_config(TIMER2_PB4_PB5_REMAP, ENABLE); #endif #ifdef TIMER1_PA15_REMAP gpio_pin_remap_config(TIMER1_PA15_REMAP, ENABLE); #endif gpio_init(ENC_A_GROUP, ENC_A_MODE, GPIO_OSPEED_50MHZ, ENC_A_PIN); gpio_init(ENC_B_GROUP, ENC_B_MODE, GPIO_OSPEED_50MHZ, ENC_B_PIN); gpio_init(ENC_PWM_GROUP, ENC_PWM_MODE, GPIO_OSPEED_50MHZ, ENC_PWM_PIN); gpio_init(ENC_I_GROUP, ENC_I_MODE, GPIO_OSPEED_50MHZ, ENC_I_PIN); } static void _io_init_irq(void) { gpio_exti_source_select(ENC_I_EXIT_SRC_GROUP, ENC_I_EXIT_SRC_PIN); exti_init(ENC_I_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING); exti_interrupt_flag_clear(ENC_I_EXTI); exti_interrupt_enable(ENC_I_EXTI); nvic_irq_enable(ENC_I_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0U); } void enc_intf_init(u32 rate) { _io_init(); enc_intf_pwm_counter(); enc_intf_quadrature_init(rate); _io_init_irq(); } void enc_intf_quadrature_init(u32 rate) { TIM_TimeBaseInitType TIM_TimeBaseStructure; TIM_ICInitType TIM_ICInitStructure; rcu_apb1_periph_clock_enable(ENC_TIMER_RCU); TIM_Module* TIMx = ENC_TIMER; //initial tim for encode TIM_DeInit(TIMx); TIM_InitTimBaseStruct(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.Period = rate - 1; TIM_TimeBaseStructure.Prescaler = 0; TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1; TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP; TIM_InitTimeBase(TIMx,&TIM_TimeBaseStructure); TIM_InitIcStruct(&TIM_ICInitStructure); TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_RISING; TIM_ICInitStructure.IcFilter = ENC_FILTER_NR; TIM_ICInitStructure.Channel = TIM_CH_1; TIM_ICInit(TIMx,&TIM_ICInitStructure); TIM_ICInitStructure.Channel = TIM_CH_2; TIM_ICInit(TIMx,&TIM_ICInitStructure); //qr encode set TIM_ConfigEncoderInterface(TIMx,TIM_ENCODE_MODE_TI12,TIM_IC_POLARITY_FALLING,TIM_IC_POLARITY_RISING); TIM_ConfigArPreload(TIMx,ENABLE); TIM_SetCnt(TIMx,0); TIM_Enable(TIMx,ENABLE); TIM_ClearFlag(TIMx,TIM_FLAG_UPDATE); TIM_ConfigInt(TIMx,TIM_INT_UPDATE,ENABLE); } void enc_intf_pwm_counter(void) { TIM_TimeBaseInitType TIM_TimeBaseStructure; TIM_ICInitType TIM_ICInitStructure; rcu_apb1_periph_clock_enable(ENC_PWM_TIMER_RCU); TIM_Module* TIMx = ENC_PWM_TIMER; TIM_DeInit(TIMx); TIM_InitTimBaseStruct(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.Period = 65535; TIM_TimeBaseStructure.Prescaler = TIM_PWM_CLK/PWM_TIME_CLK - 1; TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1; TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP; TIM_InitTimeBase(TIMx,&TIM_TimeBaseStructure); TIM_ICInitStructure.Channel = ENC_PWM_TIMER_CHAN; TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_RISING; TIM_ICInitStructure.IcSelection = TIM_IC_SELECTION_DIRECTTI; TIM_ICInitStructure.IcPrescaler = TIM_IC_PSC_DIV1; TIM_ICInitStructure.IcFilter = ENC_FILTER_NR; TIM_ConfigPwmIc(TIMx, &TIM_ICInitStructure); /* Select the TIM3 Input Trigger: TI2FP2 */ TIM_SelectInputTrig(TIMx, TIM_TRIG_SEL_TI1FP1); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIMx, TIM_SLAVE_MODE_RESET); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIMx, TIM_MASTER_SLAVE_MODE_ENABLE); /* TIM enable counter */ TIM_Enable(TIMx, ENABLE); TIM_ClearFlag(TIMx,ENC_PWM_TIMER_INT_FLG); /* Enable the CC2 Interrupt Request */ TIM_ConfigInt(TIMx, ENC_PWM_TIMER_IRQ_CH, ENABLE); nvic_irq_enable(ENC_PWM_TIMER_IRQ, ENC_PWM_IRQ_PRIORITY, 0); } __weak void ENC_TIMER_Overflow(void) { } void ENC_TIMER_IRQHandler(void) { if (SET == TIM_GetIntStatus(ENC_TIMER, TIM_INT_UPDATE)) { TIM_ClrIntPendingBit(ENC_TIMER, TIM_INT_UPDATE); ENC_TIMER_Overflow(); } } __weak void ENC_ABI_IRQHandler(void) { } void ABI_I_IRQHandler(void) { ENC_ABI_IRQHandler(); } __weak void ENC_PWM_Duty_Handler(float t, float d) { } static float pwm_freq = 0.0f; void ENC_PWM_IRQHandler(void) { if(SET == TIM_GetIntStatus(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG)){ /* clear channel 0 interrupt bit */ TIM_ClrIntPendingBit(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG); /* read channel 0 capture value */ u32 ic0value = TIMER_CH0CV(ENC_PWM_TIMER)+1; u32 ic1value = TIMER_CH1CV(ENC_PWM_TIMER)+1; float p_calc = ENC_PWM_Calc_P(ic0value); float d_calc = ENC_PWM_Calc_P(ic1value); ENC_PWM_Duty_Handler(p_calc, d_calc); pwm_freq = (float)PWM_TIME_CLK/((float)ic0value); } } float enc_get_pwm_freq(void) { return pwm_freq; }