1
0
Эх сурвалжийг харах

[stm32][pm]lptimer is supported

wdfk-prog 9 сар өмнө
parent
commit
568356cc48

+ 118 - 89
bsp/stm32/libraries/HAL_Drivers/drivers/drv_pm.c

@@ -1,22 +1,51 @@
 /*
- * 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 supported
  */
 
 #include <board.h>
 #include <drv_lptim.h>
 #include <rtdevice.h>
+#include <hwtimer.h>
 
-static void uart_console_reconfig(void)
+/*#define DRV_DEBUG*/
+#define LOG_TAG             "drv.pm"
+#include <drv_log.h>
+
+#ifdef RT_USING_PM
+
+#ifndef BSP_USING_PM_TIMER
+/*
+! Using LPTIM timer, the maximum sleep time is 65535, less than 1 min. Use RTC alarm timers for longer periods.
+! For example: packages can be used :https://packages.rt-thread.org/detail.html?package=multi_rtimer
+*/
+#ifdef BSP_USING_LPTIM1
+#define BSP_USING_PM_TIMER "lptim1"
+#elif BSP_USING_LPTIM2
+#define BSP_USING_PM_TIMER "lptim2"
+#elif BSP_USING_LPTIM3
+#define BSP_USING_PM_TIMER "lptim3"
+#else
+#error "Please define BSP_USING_PM_TIMER"
+#endif
+
+static rt_device_t timer = RT_NULL;
+
+/* Re-configure the system clock */
+rt_weak void SystemClock_ReConfig(uint8_t run_mode)
 {
-    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+    /*todo add your code here*/
+}
 
-    rt_device_control(rt_console_get_device(), RT_DEVICE_CTRL_CONFIG, &config);
+rt_weak void stm32_pm_device_run(struct rt_pm *pm, uint8_t mode)
+{
+    /*todo add your code here*/
 }
 
 /**
@@ -32,7 +61,6 @@ static void sleep(struct rt_pm *pm, uint8_t mode)
         break;
 
     case PM_SLEEP_MODE_IDLE:
-        // __WFI();
         break;
 
     case PM_SLEEP_MODE_LIGHT:
@@ -49,10 +77,12 @@ static void sleep(struct rt_pm *pm, uint8_t mode)
         break;
 
     case PM_SLEEP_MODE_DEEP:
+#if defined(SOC_SERIES_STM32L4)
         /* Enter STOP 2 mode  */
         HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
         /* Re-configure the system clock */
         SystemClock_ReConfig(pm->run_mode);
+#endif /* defined(SOC_SERIES_STM32L4) */
         break;
 
     case PM_SLEEP_MODE_STANDBY:
@@ -61,72 +91,15 @@ static void sleep(struct rt_pm *pm, uint8_t mode)
         break;
 
     case PM_SLEEP_MODE_SHUTDOWN:
+#if defined(SOC_SERIES_STM32L4)
         /* Enter SHUTDOWNN mode */
         HAL_PWREx_EnterSHUTDOWNMode();
+#endif /* defined(SOC_SERIES_STM32L4) */
         break;
 
-    default:
-        RT_ASSERT(0);
-        break;
-    }
-}
-
-static uint8_t run_speed[PM_RUN_MODE_MAX][2] =
-{
-    {80, 0},
-    {80, 1},
-    {24, 2},
-    {2,  3},
-};
-
-static void run(struct rt_pm *pm, uint8_t mode)
-{
-    static uint8_t last_mode;
-    static char *run_str[] = PM_RUN_MODE_NAMES;
-
-    if (mode == last_mode)
-        return;
-    last_mode = mode;
-
-    /* 1. 设置 MSI 作为 SYSCLK 时钟源,以修改 PLL */
-    SystemClock_MSI_ON();
-
-    /* 2. 根据RUN模式切换时钟频率(HSI) */
-    switch (mode)
-    {
-    case PM_RUN_MODE_HIGH_SPEED:
-    case PM_RUN_MODE_NORMAL_SPEED:
-        HAL_PWREx_DisableLowPowerRunMode();
-        SystemClock_80M();
-        /* Configure the main internal regulator output voltage (Range1 by default)*/
-        HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
-        break;
-    case PM_RUN_MODE_MEDIUM_SPEED:
-        HAL_PWREx_DisableLowPowerRunMode();
-        SystemClock_24M();
-        /* Configure the main internal regulator output voltage */
-        HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);
-        break;
-    case PM_RUN_MODE_LOW_SPEED:
-        SystemClock_2M();
-        /* Enter LP RUN mode */
-        HAL_PWREx_EnableLowPowerRunMode();
-        break;
     default:
         break;
     }
-
-    /* 3. 关闭 MSI 时钟 */
-    // SystemClock_MSI_OFF();
-
-    /* 4. 更新外设时钟 */
-    uart_console_reconfig();
-    /* Re-Configure the Systick time */
-    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND);
-    /* Re-Configure the Systick */
-    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
-
-    rt_kprintf("switch to %s mode, frequency = %d MHz\n", run_str[mode], run_speed[mode][0]);
 }
 
 /**
@@ -136,9 +109,19 @@ static void run(struct rt_pm *pm, uint8_t mode)
  *
  * @return the PM tick
  */
-static rt_tick_t stm32l4_pm_tick_from_os_tick(rt_tick_t tick)
+static rt_tick_t stm32_pm_tick_from_os_tick(rt_tick_t tick)
 {
-    rt_uint32_t freq = stm32l4_lptim_get_countfreq();
+    rt_uint32_t freq = 0;
+    rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq);
+    if(ret != RT_EOK)
+    {
+        LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret);
+        return 0;
+    }
+    else
+    {
+        LOG_D("Get PM timer %s frequency %d", timer->parent.name, freq);
+    }
 
     return (freq * tick / RT_TICK_PER_SECOND);
 }
@@ -150,18 +133,25 @@ static rt_tick_t stm32l4_pm_tick_from_os_tick(rt_tick_t tick)
  *
  * @return the OS tick
  */
-static rt_tick_t stm32l4_os_tick_from_pm_tick(rt_uint32_t tick)
+static rt_tick_t stm32_os_tick_from_pm_tick(rt_uint32_t tick)
 {
     static rt_uint32_t os_tick_remain = 0;
-    rt_uint32_t ret, freq;
+    rt_tick_t os_tick = 0;
+    rt_uint32_t freq = 0;
 
-    freq = stm32l4_lptim_get_countfreq();
-    ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq;
+    rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq);
+    if(ret != RT_EOK)
+    {
+        LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret);
+        return 0;
+    }
+
+    os_tick = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq;
 
     os_tick_remain += (tick * RT_TICK_PER_SECOND);
     os_tick_remain %= freq;
 
-    return ret;
+    return os_tick;
 }
 
 /**
@@ -174,18 +164,33 @@ static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout)
 {
     RT_ASSERT(pm != RT_NULL);
     RT_ASSERT(timeout > 0);
+    RT_ASSERT(timer != RT_NULL);
 
     if (timeout != RT_TICK_MAX)
     {
+        rt_uint32_t max_tick = 0;
+        rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_TICK_MAX, &max_tick);
+        if(ret != RT_EOK)
+        {
+            LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret);
+            return;
+        }
+
         /* Convert OS Tick to pmtimer timeout value */
-        timeout = stm32l4_pm_tick_from_os_tick(timeout);
-        if (timeout > stm32l4_lptim_get_tick_max())
+        timeout = stm32_pm_tick_from_os_tick(timeout);
+
+        if (timeout > max_tick)
         {
-            timeout = stm32l4_lptim_get_tick_max();
+            timeout = max_tick;
         }
 
         /* Enter PM_TIMER_MODE */
-        stm32l4_lptim_start(timeout);
+        ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_START, &timeout);
+        if(ret != RT_EOK)
+        {
+            LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret);
+            return;
+        }
     }
 }
 
@@ -199,7 +204,7 @@ static void pm_timer_stop(struct rt_pm *pm)
     RT_ASSERT(pm != RT_NULL);
 
     /* Reset pmtimer status */
-    stm32l4_lptim_stop();
+    rt_device_control(timer, HWTIMER_CTRL_STOP, RT_NULL);
 }
 
 /**
@@ -215,29 +220,42 @@ static rt_tick_t pm_timer_get_tick(struct rt_pm *pm)
 
     RT_ASSERT(pm != RT_NULL);
 
-    timer_tick = stm32l4_lptim_get_current_tick();
+    rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_COUNT, &timer_tick);
 
-    return stm32l4_os_tick_from_pm_tick(timer_tick);
+    if(ret != RT_EOK)
+    {
+        LOG_E("Get PM timer %s count failed %d", timer->parent.name, ret);
+        return 0;
+    }
+    else
+    {
+        return stm32_os_tick_from_pm_tick(timer_tick);
+    }
 }
 
+static const struct rt_pm_ops _ops =
+{
+    sleep,
+    stm32_pm_device_run,
+    pm_timer_start,
+    pm_timer_stop,
+    pm_timer_get_tick
+};
+
 /**
  * This function initialize the power manager
  */
 int drv_pm_hw_init(void)
 {
-    static const struct rt_pm_ops _ops =
-    {
-        sleep,
-        run,
-        pm_timer_start,
-        pm_timer_stop,
-        pm_timer_get_tick
-    };
-
     rt_uint8_t timer_mask = 0;
 
     /* Enable Power Clock */
+#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB)
     __HAL_RCC_PWR_CLK_ENABLE();
+#ifdef SOC_SERIES_STM32F1
+    __HAL_RCC_BKP_CLK_ENABLE();
+#endif
+#endif
 
     /* initialize timer mask */
     timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
@@ -245,7 +263,18 @@ int drv_pm_hw_init(void)
     /* initialize system pm module */
     rt_system_pm_init(&_ops, timer_mask, RT_NULL);
 
-    return 0;
+    timer = rt_device_find(BSP_USING_PM_TIMER);
+
+    if(timer == RT_NULL)
+    {
+        LOG_E("Can't find PM timer device");
+        return -RT_ERROR;
+    }
+    else
+    {
+        return rt_device_init(timer);
+    }
 }
 
-INIT_BOARD_EXPORT(drv_pm_hw_init);
+INIT_CORE_EXPORT(drv_pm_hw_init);
+#endif /* RT_USING_PM */

+ 4 - 4
bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c

@@ -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
  *
@@ -22,7 +22,7 @@
 #define RTC_BKP_DR1 RT_NULL
 #endif
 
-//#define DRV_DEBUG
+/* #define DRV_DEBUG*/
 #define LOG_TAG             "drv.rtc"
 #include <drv_log.h>
 
@@ -393,7 +393,7 @@ static rt_err_t rtc_alarm_time_set(struct rtc_device_object* p_dev)
 
 void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
 {
-    //LOG_D("rtc alarm isr.\n");
+    /*LOG_D("rtc alarm isr.\n");*/
     rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
 }
 
@@ -424,5 +424,5 @@ static int rt_hw_rtc_init(void)
 
     return RT_EOK;
 }
-INIT_DEVICE_EXPORT(rt_hw_rtc_init);
+INIT_BOARD_EXPORT(rt_hw_rtc_init);
 #endif /* BSP_USING_ONCHIP_RTC */