修正 pwm 驱动

Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
2023-02-13 08:48:46 +08:00
parent b2d3238dc2
commit a8e6be3cfe

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006-2022, RT-Thread Development Team * Copyright (c) 2006-2023, RT-Thread Development Team
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
@@ -11,7 +11,7 @@
#include <board.h> #include <board.h>
#ifdef RT_USING_PWM #ifdef BSP_USING_PWM
#include "drv_config.h" #include "drv_config.h"
#include <drivers/rt_drv_pwm.h> #include <drivers/rt_drv_pwm.h>
@@ -21,7 +21,44 @@
#define MAX_PERIOD 65535 #define MAX_PERIOD 65535
#define MIN_PERIOD 3 #define MIN_PERIOD 3
#define MIN_PULSE 2 #define MIN_PULSE 1
/* 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
}
extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); extern void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
@@ -159,68 +196,26 @@ static struct stm32_pwm stm32_pwm_obj[] =
#endif #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) static rt_uint64_t tim_clock_get(TIM_HandleTypeDef *htim)
{ {
rt_uint32_t pclk1_doubler, pclk2_doubler; rt_uint32_t pclk1_doubler, pclk2_doubler;
rt_uint64_t tim_clock; 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) /* Some series may only have APBPERIPH_BASE, don't have HAL_RCC_GetPCLK2Freq */
if (htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11) #if defined(APBPERIPH_BASE)
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)|| defined(SOC_SERIES_STM32F3) tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
if (htim->Instance == TIM15 || htim->Instance == TIM16 || htim->Instance == TIM17) #elif defined(APB1PERIPH_BASE) || defined(APB2PERIPH_BASE)
#elif defined(SOC_SERIES_STM32MP1) if ((rt_uint32_t)htim->Instance >= APB2PERIPH_BASE)
if (htim->Instance == TIM4)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
if (0)
#endif
{ {
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler); tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler);
#endif
} }
else else
{ {
tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler); tim_clock = (rt_uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler);
} }
#endif
return tim_clock; return tim_clock;
} }
@@ -312,9 +307,10 @@ static rt_err_t drv_pwm_set(TIM_HandleTypeDef *htim, struct rt_pwm_configuration
{ {
pulse = MIN_PULSE; pulse = MIN_PULSE;
} }
else if (pulse > period) /*To determine user input, output high level is required*/
else if (pulse >= period)
{ {
pulse = period; pulse = period + 1;
} }
__HAL_TIM_SET_COMPARE(htim, channel, pulse - 1); __HAL_TIM_SET_COMPARE(htim, channel, pulse - 1);
@@ -396,7 +392,7 @@ static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg
case PWM_CMD_GET: case PWM_CMD_GET:
return drv_pwm_get(htim, configuration); return drv_pwm_get(htim, configuration);
default: default:
return RT_EINVAL; return -RT_EINVAL;
} }
} }
@@ -442,13 +438,16 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
goto __exit; goto __exit;
} }
master_config.MasterOutputTrigger = TIM_TRGO_RESET; if(IS_TIM_MASTER_INSTANCE(tim->Instance))
master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
{ {
LOG_E("%s master config failed", device->name); master_config.MasterOutputTrigger = TIM_TRGO_RESET;
result = -RT_ERROR; master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
goto __exit; if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
{
LOG_E("%s master config failed", device->name);
result = -RT_ERROR;
goto __exit;
}
} }
oc_config.OCMode = TIM_OCMODE_PWM1; oc_config.OCMode = TIM_OCMODE_PWM1;
@@ -631,6 +630,15 @@ static void pwm_get_channel(void)
#ifdef BSP_USING_PWM12_CH2 #ifdef BSP_USING_PWM12_CH2
stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 1; stm32_pwm_obj[PWM12_INDEX].channel |= 1 << 1;
#endif #endif
#ifdef BSP_USING_PWM13_CH1
stm32_pwm_obj[PWM13_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM14_CH1
stm32_pwm_obj[PWM14_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM15_CH1
stm32_pwm_obj[PWM15_INDEX].channel |= 1 << 0;
#endif
#ifdef BSP_USING_PWM16_CH1 #ifdef BSP_USING_PWM16_CH1
stm32_pwm_obj[PWM16_INDEX].channel |= 1 << 0; stm32_pwm_obj[PWM16_INDEX].channel |= 1 << 0;
#endif #endif
@@ -676,4 +684,4 @@ __exit:
return result; return result;
} }
//INIT_DEVICE_EXPORT(stm32_pwm_init); //INIT_DEVICE_EXPORT(stm32_pwm_init);
#endif /* RT_USING_PWM */ #endif /* BSP_USING_PWM */