diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript index a07e753955..3a836bd427 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript @@ -52,8 +52,10 @@ if GetDepend(['RT_USING_DAC']): if GetDepend(['RT_USING_CAN']): src += ['drv_can.c'] -if GetDepend(['RT_USING_PM', 'SOC_SERIES_STM32L4']): +if GetDepend(['RT_USING_PM']): src += ['drv_pm.c'] + +if GetDepend(['BSP_USING_LPTIM']): src += ['drv_lptim.c'] if GetDepend('BSP_USING_SDRAM'): diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h new file mode 100644 index 0000000000..794289d88a --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-07-11 wdfk-prog first version + */ + +#ifndef __LPTIM_CONFIG_H__ +#define __LPTIM_CONFIG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LPTIM_DEV_INFO_CONFIG +#define LPTIM_DEV_INFO_CONFIG \ + { \ + .maxfreq = 1000000, \ + .minfreq = 3000, \ + .maxcnt = 0xFFFF, \ + .cntmode = HWTIMER_CNTMODE_UP, \ + } +#endif /* TIM_DEV_INFO_CONFIG */ + +#ifdef BSP_USING_LPTIM1 +#ifndef LPTIM1_CONFIG +#define LPTIM1_CONFIG \ + { \ + .tim_handle.Instance = LPTIM1, \ + .tim_irqn = LPTIM1_IRQn, \ + .name = "lptim1", \ + } +#endif /* LPTIM1_CONFIG */ +#endif /* BSP_USING_LPTIM1 */ + +#ifdef BSP_USING_LPTIM2 +#ifndef LPTIM2_CONFIG +#define LPTIM2_CONFIG \ + { \ + .tim_handle.Instance = LPTIM2, \ + .tim_irqn = LPTIM2_IRQn, \ + .name = "lptim2", \ + } +#endif /* LPTIM1_CONFIG */ +#endif /* BSP_USING_LPTIM1 */ + +#ifdef BSP_USING_LPTIM3 +#ifndef LPTIM3_CONFIG +#define LPTIM3_CONFIG \ + { \ + .tim_handle.Instance = LPTIM3, \ + .tim_irqn = LPTIM3_IRQn, \ + .name = "lptim3", \ + } +#endif /* LPTIM3_CONFIG */ +#endif /* BSP_USING_LPTIM3 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LPTIM_CONFIG_H__ */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_config.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_config.h index fdb6eef253..e7eda99b85 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -122,6 +122,7 @@ extern "C" { #include "h7/adc_config.h" #include "h7/dac_config.h" #include "h7/tim_config.h" +#include "h7/lptim_config.h" #include "h7/sdio_config.h" #include "h7/pwm_config.h" #include "h7/usbd_config.h" diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.c index 60b8b368ac..192343f5be 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.c @@ -1,123 +1,320 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-05-06 Zero-Free first version + * 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported */ #include #include +#include +#include "drv_config.h" -static LPTIM_HandleTypeDef LptimHandle; +/*#define DRV_DEBUG*/ +#define LOG_TAG "drv.lptim" +#include +#ifdef BSP_USING_LPTIM + +#define LPTIM_REG_MAX_VALUE (0xFFFF) + +enum +{ +#ifdef BSP_USING_LPTIM1 + LPTIM1_INDEX, +#endif +#ifdef BSP_USING_LPTIM2 + LPTIM2_INDEX, +#endif +#ifdef BSP_USING_LPTIM3 + LPTIM3_INDEX, +#endif +}; + +struct stm32_hw_lptimer +{ + rt_hwtimer_t time_device; + LPTIM_HandleTypeDef tim_handle; + IRQn_Type tim_irqn; + char *name; +}; + +static struct stm32_hw_lptimer stm32_hw_lptimer_obj[] = +{ +#ifdef BSP_USING_LPTIM1 + LPTIM1_CONFIG, +#endif +#ifdef BSP_USING_LPTIM2 + LPTIM2_CONFIG, +#endif +#ifdef BSP_USING_LPTIM3 + LPTIM3_CONFIG, +#endif +}; + +static const struct rt_hwtimer_info _info = LPTIM_DEV_INFO_CONFIG; + +static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) +{ + if(timer == RT_NULL) + { + LOG_E("init timer is NULL"); + return; + } + + if (state) + { + struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); + LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; + + if(tim_device == RT_NULL) + { + LOG_E("start tim_device is NULL"); + return; + } + if(tim == RT_NULL) + { + LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); + return; + } + + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; + + /* Enable LSI clock */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select the LSI clock as LPTIM peripheral clock */ + RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1; + RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + tim->Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; + tim->Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32; + tim->Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; + tim->Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; + tim->Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; + tim->Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; + + HAL_StatusTypeDef ret = HAL_LPTIM_Init(tim); + if (ret != HAL_OK) + { + LOG_E("%s init failed %d", tim_device->name, ret); + } + else + { + NVIC_ClearPendingIRQ(LPTIM1_IRQn); + NVIC_SetPriority(LPTIM1_IRQn, 0); + NVIC_EnableIRQ(LPTIM1_IRQn); + 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) +{ + if(timer == RT_NULL) + { + LOG_E("start timer is NULL"); + return -RT_EINVAL; + } + + struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); + LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; + + if(tim_device == RT_NULL) + { + LOG_E("start tim_device is NULL"); + return -RT_EINVAL; + } + if(tim == RT_NULL) + { + LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); + return -RT_EINVAL; + } + + HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Start_IT(tim, LPTIM_REG_MAX_VALUE, t); + if(ret != HAL_OK) + { + LOG_E("start %s failed %d", tim_device->name, ret); + return -RT_ERROR; + } + else + { + LOG_D("start %s success", tim_device->name); + return RT_EOK; + } +} + +static void timer_stop(rt_hwtimer_t *timer) +{ + if(timer == RT_NULL) + { + LOG_E("stop timer is NULL"); + return; + } + + struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); + LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; + + if(tim_device == RT_NULL) + { + LOG_E("stop tim_device is NULL"); + return; + } + if(tim == RT_NULL) + { + LOG_E("stop %s LPTIM_Handle is NULL", tim_device->name); + return; + } + + HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Stop_IT(tim); + if(ret != HAL_OK) + { + LOG_E("stop %s failed %d", tim_device->name, ret); + } + else + { + LOG_D("stop %s success", tim_device->name); + } +} + +static rt_uint32_t timer_get_freq(LPTIM_HandleTypeDef *tim) +{ + /*No calculation is performed. The default initial configuration is 1000hz*/ + return 1000; +} + + +static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) +{ + LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; + return HAL_LPTIM_ReadCounter(tim); +} + +static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + if(timer == RT_NULL) + { + LOG_E("start timer is NULL"); + return -RT_EINVAL; + } + + struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); + LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; + + if(tim_device == RT_NULL) + { + LOG_E("start tim_device is NULL"); + return -RT_EINVAL; + } + if(tim == RT_NULL) + { + LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); + return -RT_EINVAL; + } + + rt_err_t result = RT_EOK; + switch (cmd) + { + case DRV_HW_LPTIMER_CTRL_GET_TICK_MAX: + { + *(rt_uint32_t *)arg = LPTIM_REG_MAX_VALUE; + break; + } + case DRV_HW_LPTIMER_CTRL_GET_FREQ: + { + *(rt_uint32_t *)arg = timer_get_freq(tim); + break; + } + case DRV_HW_LPTIMER_CTRL_START: + { + timer_start(timer, *(rt_uint32_t *)arg, HWTIMER_MODE_ONESHOT); + break; + } + case DRV_HW_LPTIMER_CTRL_GET_COUNT: + { + *(rt_uint32_t *)arg = timer_counter_get(timer); + break; + } + default: + { + result = -RT_ENOSYS; + } + break; + } + + return result; +} + +#ifdef BSP_USING_LPTIM1 void LPTIM1_IRQHandler(void) { - HAL_LPTIM_IRQHandler(&LptimHandle); -} - -void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim) -{ - /* enter interrupt */ rt_interrupt_enter(); - - /* leave interrupt */ + HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM1_INDEX].tim_handle); rt_interrupt_leave(); } +#endif -/** - * This function get current count value of LPTIM - * - * @return the count vlaue - */ -rt_uint32_t stm32l4_lptim_get_current_tick(void) +#ifdef BSP_USING_LPTIM2 +void LPTIM2_IRQHandler(void) { - return HAL_LPTIM_ReadCounter(&LptimHandle); + rt_interrupt_enter(); + HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM2_INDEX].tim_handle); + rt_interrupt_leave(); } +#endif -/** - * This function get the max value that LPTIM can count - * - * @return the max count - */ -rt_uint32_t stm32l4_lptim_get_tick_max(void) +#ifdef BSP_USING_LPTIM3 +void LPTIM3_IRQHandler(void) { - return (0xFFFF); + rt_interrupt_enter(); + HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM3_INDEX].tim_handle); + rt_interrupt_leave(); } +#endif -/** - * This function start LPTIM with reload value - * - * @param reload The value that LPTIM count down from - * - * @return RT_EOK - */ -rt_err_t stm32l4_lptim_start(rt_uint32_t reload) +static const struct rt_hwtimer_ops _ops = { - HAL_LPTIM_TimeOut_Start_IT(&LptimHandle, 0xFFFF, reload); - - return (RT_EOK); -} - -/** - * This function stop LPTIM - */ -void stm32l4_lptim_stop(void) -{ - rt_uint32_t _ier; - - _ier = LptimHandle.Instance->IER; - LptimHandle.Instance->ICR = LptimHandle.Instance->ISR & _ier; -} - -/** - * This function get the count clock of LPTIM - * - * @return the count clock frequency in Hz - */ -rt_uint32_t stm32l4_lptim_get_countfreq(void) -{ - return 32000 / 32; -} + .init = timer_init, + .start = timer_start, + .stop = timer_stop, + .count_get = timer_counter_get, + .control = timer_ctrl, +}; /** * This function initialize the lptim */ -int stm32l4_hw_lptim_init(void) +static int stm32_hw_lptim_init(void) { - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; + int i = 0; + int result = RT_EOK; - /* Enable LSI clock */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; - RCC_OscInitStruct.LSIState = RCC_LSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - HAL_RCC_OscConfig(&RCC_OscInitStruct); - - /* Select the LSI clock as LPTIM peripheral clock */ - RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1; - RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI; - HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); - - LptimHandle.Instance = LPTIM1; - LptimHandle.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; - LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32; - LptimHandle.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; - LptimHandle.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; - LptimHandle.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; - LptimHandle.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; - if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK) + for (i = 0; i < sizeof(stm32_hw_lptimer_obj) / sizeof(stm32_hw_lptimer_obj[0]); i++) { - return -1; + stm32_hw_lptimer_obj[i].time_device.info = &_info; + stm32_hw_lptimer_obj[i].time_device.ops = &_ops; + if (rt_device_hwtimer_register(&stm32_hw_lptimer_obj[i].time_device, stm32_hw_lptimer_obj[i].name, &stm32_hw_lptimer_obj[i].tim_handle) == RT_EOK) + { + LOG_D("%s register success", stm32_hw_lptimer_obj[i].name); + } + else + { + LOG_E("%s register failed", stm32_hw_lptimer_obj[i].name); + result = -RT_ERROR; + } } - NVIC_ClearPendingIRQ(LPTIM1_IRQn); - NVIC_SetPriority(LPTIM1_IRQn, 0); - NVIC_EnableIRQ(LPTIM1_IRQn); - - return 0; + return result; } -INIT_DEVICE_EXPORT(stm32l4_hw_lptim_init); +INIT_BOARD_EXPORT(stm32_hw_lptim_init); +#endif /* BSP_USING_LPTIM */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.h index 79f3e11753..124242abb5 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_lptim.h @@ -1,11 +1,12 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-05-06 Zero-Free first version + * 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported */ #ifndef __DRV_PMTIMER_H__ @@ -13,11 +14,13 @@ #include -rt_uint32_t stm32l4_lptim_get_countfreq(void); -rt_uint32_t stm32l4_lptim_get_tick_max(void); -rt_uint32_t stm32l4_lptim_get_current_tick(void); - -rt_err_t stm32l4_lptim_start(rt_uint32_t load); -void stm32l4_lptim_stop(void); +/* 0x20 - 0x3F udevice control commands*/ +typedef enum +{ + DRV_HW_LPTIMER_CTRL_GET_TICK_MAX = 0x20, /* get the maximum tick value*/ + DRV_HW_LPTIMER_CTRL_GET_FREQ = 0X21, /* get the timer frequency*/ + DRV_HW_LPTIMER_CTRL_START = 0X22, /* set the timeout value*/ + DRV_HW_LPTIMER_CTRL_GET_COUNT = 0X23, /* get the current count value*/ +} drv_hw_lptimer_ctrl_t; #endif /* __DRV_PMTIMER_H__ */ diff --git a/bsp/stm32/stm32h750-artpi/board/Kconfig b/bsp/stm32/stm32h750-artpi/board/Kconfig index 63ca343eb7..122d147adb 100644 --- a/bsp/stm32/stm32h750-artpi/board/Kconfig +++ b/bsp/stm32/stm32h750-artpi/board/Kconfig @@ -224,6 +224,23 @@ menu "On-chip Peripheral Drivers" endif endif + menuconfig BSP_USING_LPTIM + bool "Enable lptimer" + default n + select RT_USING_LPTIMER + select RT_USING_HWTIMER + if BSP_USING_LPTIM + config BSP_USING_LPTIM1 + bool "Enable LPTIM1" + default n + config BSP_USING_LPTIM2 + bool "Enable LPTIM2" + default n + config BSP_USING_LPTIM3 + bool "Enable LPTIM3" + default n + endif + menuconfig BSP_USING_SPI bool "Enable SPI" default n