@@ -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,6 +438,8 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(IS_TIM_MASTER_INSTANCE(tim->Instance))
|
||||||
|
{
|
||||||
master_config.MasterOutputTrigger = TIM_TRGO_RESET;
|
master_config.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
|
if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK)
|
||||||
@@ -450,6 +448,7 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device)
|
|||||||
result = -RT_ERROR;
|
result = -RT_ERROR;
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
oc_config.OCMode = TIM_OCMODE_PWM1;
|
oc_config.OCMode = TIM_OCMODE_PWM1;
|
||||||
oc_config.Pulse = 0;
|
oc_config.Pulse = 0;
|
||||||
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user