From a24f527990c481546f323cde5d80e950451c2a99 Mon Sep 17 00:00:00 2001 From: "Man, Jianting (Meco)" <920369182@qq.com> Date: Sun, 6 Nov 2022 22:58:39 -0500 Subject: [stm32][tim/pwm] 抽出公共代码,防止日后演进出现分歧 (#6575) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [stm32][tim/pwm] 抽出公共代码,防止日后演进出现分歧 * Update drv_tim.c --- bsp/stm32/libraries/HAL_Drivers/SConscript | 8 +- bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c | 623 -------------------------- bsp/stm32/libraries/HAL_Drivers/drv_pwm.c | 44 +- bsp/stm32/libraries/HAL_Drivers/drv_tim.c | 623 ++++++++++++++++++++++++++ bsp/stm32/libraries/HAL_Drivers/drv_tim.h | 18 + bsp/stm32/libraries/HAL_Drivers/drv_usart.h | 4 +- 6 files changed, 652 insertions(+), 668 deletions(-) delete mode 100644 bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c create mode 100644 bsp/stm32/libraries/HAL_Drivers/drv_tim.c create mode 100644 bsp/stm32/libraries/HAL_Drivers/drv_tim.h (limited to 'bsp') diff --git a/bsp/stm32/libraries/HAL_Drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/SConscript index f066538df1..d929ca149e 100644 --- a/bsp/stm32/libraries/HAL_Drivers/SConscript +++ b/bsp/stm32/libraries/HAL_Drivers/SConscript @@ -16,11 +16,11 @@ if GetDepend(['RT_USING_SERIAL']): else: src += ['drv_usart.c'] -if GetDepend(['RT_USING_HWTIMER']): - src += ['drv_hwtimer.c'] +if GetDepend(['BSP_USING_TIM']): + src += ['drv_tim.c'] -if GetDepend(['RT_USING_PWM']): - src += ['drv_pwm.c'] +if GetDepend(['BSP_USING_PWM']): + src += ['drv_pwm.c', 'drv_tim.c'] if GetDepend(['RT_USING_SPI']): src += ['drv_spi.c'] diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c b/bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c deleted file mode 100644 index c44fe83331..0000000000 --- a/bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-12-10 zylx first version - * 2020-06-16 thread-liu Porting for stm32mp1 - * 2020-08-25 linyongkang Fix the timer clock frequency doubling problem - * 2020-10-14 Dozingfiretruck Porting for stm32wbxx - * 2020-11-18 leizhixiong add STM32H7 series support - */ - -#include - -#ifdef BSP_USING_TIM -#include "drv_config.h" - -//#define DRV_DEBUG -#define LOG_TAG "drv.hwtimer" -#include - -#ifdef RT_USING_HWTIMER -enum -{ -#ifdef BSP_USING_TIM1 - TIM1_INDEX, -#endif -#ifdef BSP_USING_TIM2 - TIM2_INDEX, -#endif -#ifdef BSP_USING_TIM3 - TIM3_INDEX, -#endif -#ifdef BSP_USING_TIM4 - TIM4_INDEX, -#endif -#ifdef BSP_USING_TIM5 - TIM5_INDEX, -#endif -#ifdef BSP_USING_TIM6 - TIM6_INDEX, -#endif -#ifdef BSP_USING_TIM7 - TIM7_INDEX, -#endif -#ifdef BSP_USING_TIM8 - TIM8_INDEX, -#endif -#ifdef BSP_USING_TIM9 - TIM9_INDEX, -#endif -#ifdef BSP_USING_TIM10 - TIM10_INDEX, -#endif -#ifdef BSP_USING_TIM11 - TIM11_INDEX, -#endif -#ifdef BSP_USING_TIM12 - TIM12_INDEX, -#endif -#ifdef BSP_USING_TIM13 - TIM13_INDEX, -#endif -#ifdef BSP_USING_TIM14 - TIM14_INDEX, -#endif -#ifdef BSP_USING_TIM15 - TIM15_INDEX, -#endif -#ifdef BSP_USING_TIM16 - TIM16_INDEX, -#endif -#ifdef BSP_USING_TIM17 - TIM17_INDEX, -#endif -}; - -struct stm32_hwtimer -{ - rt_hwtimer_t time_device; - TIM_HandleTypeDef tim_handle; - IRQn_Type tim_irqn; - char *name; -}; - -static struct stm32_hwtimer stm32_hwtimer_obj[] = -{ -#ifdef BSP_USING_TIM1 - TIM1_CONFIG, -#endif - -#ifdef BSP_USING_TIM2 - TIM2_CONFIG, -#endif - -#ifdef BSP_USING_TIM3 - TIM3_CONFIG, -#endif - -#ifdef BSP_USING_TIM4 - TIM4_CONFIG, -#endif - -#ifdef BSP_USING_TIM5 - TIM5_CONFIG, -#endif - -#ifdef BSP_USING_TIM6 - TIM6_CONFIG, -#endif - -#ifdef BSP_USING_TIM7 - TIM7_CONFIG, -#endif - -#ifdef BSP_USING_TIM8 - TIM8_CONFIG, -#endif - -#ifdef BSP_USING_TIM9 - TIM9_CONFIG, -#endif - -#ifdef BSP_USING_TIM10 - TIM10_CONFIG, -#endif - -#ifdef BSP_USING_TIM11 - TIM11_CONFIG, -#endif - -#ifdef BSP_USING_TIM12 - TIM12_CONFIG, -#endif - -#ifdef BSP_USING_TIM13 - TIM13_CONFIG, -#endif - -#ifdef BSP_USING_TIM14 - TIM14_CONFIG, -#endif - -#ifdef BSP_USING_TIM15 - TIM15_CONFIG, -#endif - -#ifdef BSP_USING_TIM16 - TIM16_CONFIG, -#endif - -#ifdef BSP_USING_TIM17 - TIM17_CONFIG, -#endif -}; - -/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */ -static void pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler) -{ - rt_uint32_t flatency = 0; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - - RT_ASSERT(pclk1_doubler != RT_NULL); - RT_ASSERT(pclk1_doubler != RT_NULL); - - HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency); - - *pclk1_doubler = 1; - *pclk2_doubler = 1; - -#if defined(SOC_SERIES_STM32MP1) - if (RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1) - { - *pclk1_doubler = 2; - } - if (RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1) - { - *pclk2_doubler = 2; - } -#else - if (RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1) - { - *pclk1_doubler = 2; - } -#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) - if (RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1) - { - *pclk2_doubler = 2; - } -#endif -#endif -} - -static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) -{ - uint32_t prescaler_value = 0; - uint32_t pclk1_doubler, pclk2_doubler; - TIM_HandleTypeDef *tim = RT_NULL; - struct stm32_hwtimer *tim_device = RT_NULL; - - RT_ASSERT(timer != RT_NULL); - if (state) - { - tim = (TIM_HandleTypeDef *)timer->parent.user_data; - tim_device = (struct stm32_hwtimer *)timer; - - pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); - - /* time init */ -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) - if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11) -#elif defined(SOC_SERIES_STM32L4) - if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32WB) - if (tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32MP1) - if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) - if (0) -#else -#error "This driver has not supported this series yet!" -#endif - { -#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) - prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler / 10000) - 1; -#endif - } - else - { - prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1; - } - tim->Init.Period = 10000 - 1; - tim->Init.Prescaler = prescaler_value; - tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - if (timer->info->cntmode == HWTIMER_CNTMODE_UP) - { - tim->Init.CounterMode = TIM_COUNTERMODE_UP; - } - else - { - tim->Init.CounterMode = TIM_COUNTERMODE_DOWN; - } - tim->Init.RepetitionCounter = 0; -#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) - tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; -#endif - if (HAL_TIM_Base_Init(tim) != HAL_OK) - { - LOG_E("%s init failed", tim_device->name); - return; - } - else - { - /* set the TIMx priority */ - HAL_NVIC_SetPriority(tim_device->tim_irqn, 3, 0); - - /* enable the TIMx global Interrupt */ - HAL_NVIC_EnableIRQ(tim_device->tim_irqn); - - /* clear update flag */ - __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE); - /* enable update request source */ - __HAL_TIM_URS_ENABLE(tim); - - LOG_D("%s init success", tim_device->name); - } - } -} - -static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) -{ - rt_err_t result = RT_EOK; - TIM_HandleTypeDef *tim = RT_NULL; - - RT_ASSERT(timer != RT_NULL); - - tim = (TIM_HandleTypeDef *)timer->parent.user_data; - - /* set tim cnt */ - __HAL_TIM_SET_COUNTER(tim, 0); - /* set tim arr */ - __HAL_TIM_SET_AUTORELOAD(tim, t - 1); - - if (opmode == HWTIMER_MODE_ONESHOT) - { - /* set timer to single mode */ - tim->Instance->CR1 |= TIM_OPMODE_SINGLE; - } - else - { - tim->Instance->CR1 &= (~TIM_OPMODE_SINGLE); - } - - /* start timer */ - if (HAL_TIM_Base_Start_IT(tim) != HAL_OK) - { - LOG_E("TIM start failed"); - result = -RT_ERROR; - } - - return result; -} - -static void timer_stop(rt_hwtimer_t *timer) -{ - TIM_HandleTypeDef *tim = RT_NULL; - - RT_ASSERT(timer != RT_NULL); - - tim = (TIM_HandleTypeDef *)timer->parent.user_data; - - /* stop timer */ - HAL_TIM_Base_Stop_IT(tim); - - /* set tim cnt */ - __HAL_TIM_SET_COUNTER(tim, 0); -} - -static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) -{ - TIM_HandleTypeDef *tim = RT_NULL; - rt_err_t result = -RT_ERROR; - uint32_t pclk1_doubler, pclk2_doubler; - - RT_ASSERT(timer != RT_NULL); - RT_ASSERT(arg != RT_NULL); - - tim = (TIM_HandleTypeDef *)timer->parent.user_data; - - switch (cmd) - { - case HWTIMER_CTRL_FREQ_SET: - { - rt_uint32_t freq; - rt_uint16_t val; - - /* set timer frequence */ - freq = *((rt_uint32_t *)arg); - - pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); - -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) - if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11) -#elif defined(SOC_SERIES_STM32L4) - if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32WB) - if (tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32MP1) - if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17) -#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) - if (0) -#endif - { -#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) - val = HAL_RCC_GetPCLK2Freq() * pclk2_doubler / freq; -#endif - } - else - { - val = HAL_RCC_GetPCLK1Freq() * pclk1_doubler / freq; - } - __HAL_TIM_SET_PRESCALER(tim, val - 1); - - /* Update frequency value */ - tim->Instance->EGR |= TIM_EVENTSOURCE_UPDATE; - - result = RT_EOK; - } - break; - default: - { - result = -RT_EINVAL; - } - break; - } - - return result; -} - -static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) -{ - TIM_HandleTypeDef *tim = RT_NULL; - - RT_ASSERT(timer != RT_NULL); - - tim = (TIM_HandleTypeDef *)timer->parent.user_data; - - return tim->Instance->CNT; -} - -static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG; - -static const struct rt_hwtimer_ops _ops = -{ - .init = timer_init, - .start = timer_start, - .stop = timer_stop, - .count_get = timer_counter_get, - .control = timer_ctrl, -}; - -#ifdef BSP_USING_TIM2 -void TIM2_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM2_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM3 -void TIM3_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM3_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM4 -void TIM4_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM4_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM5 -void TIM5_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM5_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM7 -void TIM7_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM7_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM11 -void TIM1_TRG_COM_TIM11_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM11_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM13 -void TIM8_UP_TIM13_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM13_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM14 -#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) - void TIM8_TRG_COM_TIM14_IRQHandler(void) -#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) - void TIM14_IRQHandler(void) -#endif -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM14_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM15 -void TIM1_BRK_TIM15_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM15_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM16 -#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) - void TIM1_UP_TIM16_IRQHandler(void) -#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) - void TIM16_IRQHandler(void) -#endif -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM16_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif -#ifdef BSP_USING_TIM17 -#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) - void TIM1_TRG_COM_TIM17_IRQHandler(void) -#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) - void TIM17_IRQHandler(void) -#endif -{ - /* enter interrupt */ - rt_interrupt_enter(); - HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM17_INDEX].tim_handle); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif - -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ -#ifdef BSP_USING_TIM2 - if (htim->Instance == TIM2) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM2_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM3 - if (htim->Instance == TIM3) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM3_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM4 - if (htim->Instance == TIM4) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM4_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM5 - if (htim->Instance == TIM5) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM5_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM7 - if (htim->Instance == TIM7) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM7_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM11 - if (htim->Instance == TIM11) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM11_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM13 - if (htim->Instance == TIM13) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM13_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM14 - if (htim->Instance == TIM14) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM14_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM15 - if (htim->Instance == TIM15) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM15_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM16 - if (htim->Instance == TIM16) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM16_INDEX].time_device); - } -#endif -#ifdef BSP_USING_TIM17 - if (htim->Instance == TIM17) - { - rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM17_INDEX].time_device); - } -#endif -} - -static int stm32_hwtimer_init(void) -{ - int i = 0; - int result = RT_EOK; - - for (i = 0; i < sizeof(stm32_hwtimer_obj) / sizeof(stm32_hwtimer_obj[0]); i++) - { - stm32_hwtimer_obj[i].time_device.info = &_info; - stm32_hwtimer_obj[i].time_device.ops = &_ops; - if (rt_device_hwtimer_register(&stm32_hwtimer_obj[i].time_device, - stm32_hwtimer_obj[i].name, &stm32_hwtimer_obj[i].tim_handle) == RT_EOK) - { - LOG_D("%s register success", stm32_hwtimer_obj[i].name); - } - else - { - LOG_E("%s register failed", stm32_hwtimer_obj[i].name); - result = -RT_ERROR; - } - } - - return result; -} -INIT_BOARD_EXPORT(stm32_hwtimer_init); - -#endif /* RT_USING_HWTIMER */ -#endif /* BSP_USING_TIM */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c b/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c index ec9bf701ed..46b70e2a57 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c @@ -13,6 +13,7 @@ #ifdef BSP_USING_PWM #include "drv_config.h" +#include "drv_tim.h" #include //#define DRV_DEBUG @@ -159,58 +160,23 @@ static struct stm32_pwm stm32_pwm_obj[] = #endif }; -/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */ -static void pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler) -{ - uint32_t flatency = 0; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - - RT_ASSERT(pclk1_doubler != RT_NULL); - RT_ASSERT(pclk1_doubler != RT_NULL); - - HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency); - - *pclk1_doubler = 1; - *pclk2_doubler = 1; - -#if defined(SOC_SERIES_STM32MP1) - if (RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1) - { - *pclk1_doubler = 2; - } - if (RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1) - { - *pclk2_doubler = 2; - } -#else - if (RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1) - { - *pclk1_doubler = 2; - } -#if !(defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)) - if (RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1) - { - *pclk2_doubler = 2; - } -#endif -#endif -} - static rt_uint64_t tim_clock_get(TIM_HandleTypeDef *htim) { rt_uint32_t pclk1_doubler, pclk2_doubler; rt_uint64_t tim_clock; - pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); + stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11) -#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)|| defined(SOC_SERIES_STM32F3) +#elif defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7) if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17) #elif defined(SOC_SERIES_STM32MP1) if (htim->Instance == TIM4) #elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) if (0) +#else +#error "This driver has not supported this series yet!" #endif { #if !(defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)) /* don't have HAL_RCC_GetPCLK2Freq */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_tim.c b/bsp/stm32/libraries/HAL_Drivers/drv_tim.c new file mode 100644 index 0000000000..98efc98bc3 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drv_tim.c @@ -0,0 +1,623 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-12-10 zylx first version + * 2020-06-16 thread-liu Porting for stm32mp1 + * 2020-08-25 linyongkang Fix the timer clock frequency doubling problem + * 2020-10-14 Dozingfiretruck Porting for stm32wbxx + * 2020-11-18 leizhixiong add STM32H7 series support + */ + +#include +#include "drv_config.h" + +//#define DRV_DEBUG +#define LOG_TAG "drv.tim" +#include + +/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */ +void stm32_tim_pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler) +{ + rt_uint32_t flatency = 0; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + RT_ASSERT(pclk1_doubler != RT_NULL); + RT_ASSERT(pclk1_doubler != RT_NULL); + + HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency); + + *pclk1_doubler = 1; + *pclk2_doubler = 1; + +#if defined(SOC_SERIES_STM32MP1) + if (RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1) + { + *pclk1_doubler = 2; + } + if (RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1) + { + *pclk2_doubler = 2; + } +#else + if (RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1) + { + *pclk1_doubler = 2; + } +#if !(defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)) + if (RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1) + { + *pclk2_doubler = 2; + } +#endif +#endif +} + +#ifdef BSP_USING_TIM + +enum +{ +#ifdef BSP_USING_TIM1 + TIM1_INDEX, +#endif +#ifdef BSP_USING_TIM2 + TIM2_INDEX, +#endif +#ifdef BSP_USING_TIM3 + TIM3_INDEX, +#endif +#ifdef BSP_USING_TIM4 + TIM4_INDEX, +#endif +#ifdef BSP_USING_TIM5 + TIM5_INDEX, +#endif +#ifdef BSP_USING_TIM6 + TIM6_INDEX, +#endif +#ifdef BSP_USING_TIM7 + TIM7_INDEX, +#endif +#ifdef BSP_USING_TIM8 + TIM8_INDEX, +#endif +#ifdef BSP_USING_TIM9 + TIM9_INDEX, +#endif +#ifdef BSP_USING_TIM10 + TIM10_INDEX, +#endif +#ifdef BSP_USING_TIM11 + TIM11_INDEX, +#endif +#ifdef BSP_USING_TIM12 + TIM12_INDEX, +#endif +#ifdef BSP_USING_TIM13 + TIM13_INDEX, +#endif +#ifdef BSP_USING_TIM14 + TIM14_INDEX, +#endif +#ifdef BSP_USING_TIM15 + TIM15_INDEX, +#endif +#ifdef BSP_USING_TIM16 + TIM16_INDEX, +#endif +#ifdef BSP_USING_TIM17 + TIM17_INDEX, +#endif +}; + +struct stm32_hwtimer +{ + rt_hwtimer_t time_device; + TIM_HandleTypeDef tim_handle; + IRQn_Type tim_irqn; + char *name; +}; + +static struct stm32_hwtimer stm32_hwtimer_obj[] = +{ +#ifdef BSP_USING_TIM1 + TIM1_CONFIG, +#endif + +#ifdef BSP_USING_TIM2 + TIM2_CONFIG, +#endif + +#ifdef BSP_USING_TIM3 + TIM3_CONFIG, +#endif + +#ifdef BSP_USING_TIM4 + TIM4_CONFIG, +#endif + +#ifdef BSP_USING_TIM5 + TIM5_CONFIG, +#endif + +#ifdef BSP_USING_TIM6 + TIM6_CONFIG, +#endif + +#ifdef BSP_USING_TIM7 + TIM7_CONFIG, +#endif + +#ifdef BSP_USING_TIM8 + TIM8_CONFIG, +#endif + +#ifdef BSP_USING_TIM9 + TIM9_CONFIG, +#endif + +#ifdef BSP_USING_TIM10 + TIM10_CONFIG, +#endif + +#ifdef BSP_USING_TIM11 + TIM11_CONFIG, +#endif + +#ifdef BSP_USING_TIM12 + TIM12_CONFIG, +#endif + +#ifdef BSP_USING_TIM13 + TIM13_CONFIG, +#endif + +#ifdef BSP_USING_TIM14 + TIM14_CONFIG, +#endif + +#ifdef BSP_USING_TIM15 + TIM15_CONFIG, +#endif + +#ifdef BSP_USING_TIM16 + TIM16_CONFIG, +#endif + +#ifdef BSP_USING_TIM17 + TIM17_CONFIG, +#endif +}; + +static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) +{ + uint32_t prescaler_value = 0; + uint32_t pclk1_doubler, pclk2_doubler; + TIM_HandleTypeDef *tim = RT_NULL; + struct stm32_hwtimer *tim_device = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + if (state) + { + tim = (TIM_HandleTypeDef *)timer->parent.user_data; + tim_device = (struct stm32_hwtimer *)timer; + + stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); + + /* time init */ +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) + if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11) +#elif defined(SOC_SERIES_STM32L4) + if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32WB) + if (tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32MP1) + if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) + if (0) +#else +#error "This driver has not supported this series yet!" +#endif + { +#if !(defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)) + prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler / 10000) - 1; +#endif + } + else + { + prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1; + } + tim->Init.Period = 10000 - 1; + tim->Init.Prescaler = prescaler_value; + tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + if (timer->info->cntmode == HWTIMER_CNTMODE_UP) + { + tim->Init.CounterMode = TIM_COUNTERMODE_UP; + } + else + { + tim->Init.CounterMode = TIM_COUNTERMODE_DOWN; + } + tim->Init.RepetitionCounter = 0; +#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) + tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; +#endif + if (HAL_TIM_Base_Init(tim) != HAL_OK) + { + LOG_E("%s init failed", tim_device->name); + return; + } + else + { + /* set the TIMx priority */ + HAL_NVIC_SetPriority(tim_device->tim_irqn, 3, 0); + + /* enable the TIMx global Interrupt */ + HAL_NVIC_EnableIRQ(tim_device->tim_irqn); + + /* clear update flag */ + __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE); + /* enable update request source */ + __HAL_TIM_URS_ENABLE(tim); + + LOG_D("%s init success", tim_device->name); + } + } +} + +static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) +{ + rt_err_t result = RT_EOK; + TIM_HandleTypeDef *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TIM_HandleTypeDef *)timer->parent.user_data; + + /* set tim cnt */ + __HAL_TIM_SET_COUNTER(tim, 0); + /* set tim arr */ + __HAL_TIM_SET_AUTORELOAD(tim, t - 1); + + if (opmode == HWTIMER_MODE_ONESHOT) + { + /* set timer to single mode */ + tim->Instance->CR1 |= TIM_OPMODE_SINGLE; + } + else + { + tim->Instance->CR1 &= (~TIM_OPMODE_SINGLE); + } + + /* start timer */ + if (HAL_TIM_Base_Start_IT(tim) != HAL_OK) + { + LOG_E("TIM start failed"); + result = -RT_ERROR; + } + + return result; +} + +static void timer_stop(rt_hwtimer_t *timer) +{ + TIM_HandleTypeDef *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TIM_HandleTypeDef *)timer->parent.user_data; + + /* stop timer */ + HAL_TIM_Base_Stop_IT(tim); + + /* set tim cnt */ + __HAL_TIM_SET_COUNTER(tim, 0); +} + +static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + TIM_HandleTypeDef *tim = RT_NULL; + rt_err_t result = -RT_ERROR; + uint32_t pclk1_doubler, pclk2_doubler; + + RT_ASSERT(timer != RT_NULL); + RT_ASSERT(arg != RT_NULL); + + tim = (TIM_HandleTypeDef *)timer->parent.user_data; + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + rt_uint32_t freq; + rt_uint16_t val; + + /* set timer frequence */ + freq = *((rt_uint32_t *)arg); + + stm32_tim_pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler); + +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) + if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11) +#elif defined(SOC_SERIES_STM32L4) + if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32WB) + if (tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32MP1) + if(tim->Instance == TIM14 || tim->Instance == TIM16 || tim->Instance == TIM17) +#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) + if (0) +#else +#error "This driver has not supported this series yet!" +#endif + { +#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0) + val = HAL_RCC_GetPCLK2Freq() * pclk2_doubler / freq; +#endif + } + else + { + val = HAL_RCC_GetPCLK1Freq() * pclk1_doubler / freq; + } + __HAL_TIM_SET_PRESCALER(tim, val - 1); + + /* Update frequency value */ + tim->Instance->EGR |= TIM_EVENTSOURCE_UPDATE; + + result = RT_EOK; + } + break; + default: + { + result = -RT_EINVAL; + } + break; + } + + return result; +} + +static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) +{ + TIM_HandleTypeDef *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TIM_HandleTypeDef *)timer->parent.user_data; + + return tim->Instance->CNT; +} + +static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG; + +static const struct rt_hwtimer_ops _ops = +{ + .init = timer_init, + .start = timer_start, + .stop = timer_stop, + .count_get = timer_counter_get, + .control = timer_ctrl, +}; + +#ifdef BSP_USING_TIM2 +void TIM2_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM2_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM3 +void TIM3_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM3_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM4 +void TIM4_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM4_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM5 +void TIM5_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM5_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM7 +void TIM7_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM7_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM11 +void TIM1_TRG_COM_TIM11_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM11_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM13 +void TIM8_UP_TIM13_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM13_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM14 +#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) + void TIM8_TRG_COM_TIM14_IRQHandler(void) +#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) + void TIM14_IRQHandler(void) +#endif +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM14_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM15 +void TIM1_BRK_TIM15_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM15_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM16 +#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) + void TIM1_UP_TIM16_IRQHandler(void) +#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) + void TIM16_IRQHandler(void) +#endif +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM16_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif +#ifdef BSP_USING_TIM17 +#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) + void TIM1_TRG_COM_TIM17_IRQHandler(void) +#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32MP1) + void TIM17_IRQHandler(void) +#endif +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM17_INDEX].tim_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ +#ifdef BSP_USING_TIM2 + if (htim->Instance == TIM2) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM2_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM3 + if (htim->Instance == TIM3) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM3_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM4 + if (htim->Instance == TIM4) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM4_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM5 + if (htim->Instance == TIM5) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM5_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM7 + if (htim->Instance == TIM7) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM7_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM11 + if (htim->Instance == TIM11) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM11_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM13 + if (htim->Instance == TIM13) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM13_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM14 + if (htim->Instance == TIM14) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM14_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM15 + if (htim->Instance == TIM15) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM15_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM16 + if (htim->Instance == TIM16) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM16_INDEX].time_device); + } +#endif +#ifdef BSP_USING_TIM17 + if (htim->Instance == TIM17) + { + rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM17_INDEX].time_device); + } +#endif +} + +static int stm32_hwtimer_init(void) +{ + int i = 0; + int result = RT_EOK; + + for (i = 0; i < sizeof(stm32_hwtimer_obj) / sizeof(stm32_hwtimer_obj[0]); i++) + { + stm32_hwtimer_obj[i].time_device.info = &_info; + stm32_hwtimer_obj[i].time_device.ops = &_ops; + if (rt_device_hwtimer_register(&stm32_hwtimer_obj[i].time_device, + stm32_hwtimer_obj[i].name, &stm32_hwtimer_obj[i].tim_handle) == RT_EOK) + { + LOG_D("%s register success", stm32_hwtimer_obj[i].name); + } + else + { + LOG_E("%s register failed", stm32_hwtimer_obj[i].name); + result = -RT_ERROR; + } + } + + return result; +} +INIT_BOARD_EXPORT(stm32_hwtimer_init); + +#endif /* BSP_USING_TIM */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_tim.h b/bsp/stm32/libraries/HAL_Drivers/drv_tim.h new file mode 100644 index 0000000000..5b1d0c1796 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drv_tim.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-01 Meco Man First version + */ + +#ifndef __DRV_TIM_H__ +#define __DRV_TIM_H__ + +#include + +void stm32_tim_pclkx_doubler_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler); + +#endif /* __DRV_TIM_H__ */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h index 7763a70683..4006f94893 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h @@ -5,8 +5,8 @@ * * Change Logs: * Date Author Notes - * 2018.10.30 SummerGift first version - * 2019.03.05 whj4674672 add stm32h7 + * 2018-10-30 SummerGift first version + * 2019-03-05 whj4674672 add stm32h7 * 2020-10-14 Dozingfiretruck Porting for stm32wbxx */ -- cgit v1.3.1