summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2019-05-10 09:30:21 +0800
committerGitHub <[email protected]>2019-05-10 09:30:21 +0800
commit1dd364b45a907935a7b67a2199e83dae582fd85b (patch)
treeacfe83b9630cdac82f4944c233d727a2cdef4d1f
parentc4cd2a1cc1d21d764487759f4b1438d86b9cad29 (diff)
parent598f2d360b3d93e4a074fce390621a8979cc5fe1 (diff)
Merge pull request #2666 from Zero-Free/pm_dev
[pm]add pm example and support for stm32l475-atk-pandora
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h2
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/board.c251
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/board.h6
-rw-r--r--components/drivers/pm/pm.c15
-rw-r--r--examples/pm/wakeup_app.c77
5 files changed, 308 insertions, 43 deletions
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
index 9fd2fdbd86..5a4d494431 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
@@ -69,7 +69,7 @@
#define HAL_IWDG_MODULE_ENABLED
/*#define HAL_LTDC_MODULE_ENABLED */
/*#define HAL_LCD_MODULE_ENABLED */
-/*#define HAL_LPTIM_MODULE_ENABLED */
+#define HAL_LPTIM_MODULE_ENABLED
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_OPAMP_MODULE_ENABLED */
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/board.c b/bsp/stm32/stm32l475-atk-pandora/board/board.c
index 3ec895bb7d..b0cec153e7 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/board.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/board.c
@@ -10,55 +10,222 @@
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
+ * 2019-05-09 Zero-Free Adding multiple configurations for system clock frequency
*/
#include <board.h>
+#include <rtthread.h>
void SystemClock_Config(void)
{
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- /**Initializes the CPU, AHB and APB busses clocks
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLM = 1;
- RCC_OscInitStruct.PLL.PLLN = 20;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
- RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
- RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /**Initializes the CPU, AHB and APB busses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ /**Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 1;
+ RCC_OscInitStruct.PLL.PLLN = 20;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /**Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2;
+ PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
+ PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /**Configure the main internal regulator output voltage
+ */
+ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+#ifdef RT_USING_PM
+
+void SystemClock_MSI_ON(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+ /* Initializes the CPU, AHB and APB busses clocks */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.MSIState = RCC_MSI_ON;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ RT_ASSERT(0);
+ }
+
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void SystemClock_MSI_OFF(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.HSIState = RCC_MSI_OFF;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* No update on PLL */
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void SystemClock_80M(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+
+ /**Initializes the CPU, AHB and APB busses clocks */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 1;
+ RCC_OscInitStruct.PLL.PLLN = 20;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
- {
- Error_Handler();
- }
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;
- PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
- PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- Error_Handler();
- }
- /**Configure the main internal regulator output voltage
+ /**Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void SystemClock_24M(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_ClkInitTypeDef RCC_ClkInitStruct;
+
+ /** Initializes the CPU, AHB and APB busses clocks */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 1;
+ RCC_OscInitStruct.PLL.PLLN = 12;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /** Initializes the CPU, AHB and APB busses clocks */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void SystemClock_2M(void)
+{
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+
+ /* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.MSIState = RCC_MSI_ON;
+ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
+ RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+
+ /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
+ clocks dividers */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+}
+
+/**
+ * @brief Configures system clock after wake-up from STOP: enable HSI, PLL
+ * and select PLL as system clock source.
+ * @param None
+ * @retval None
*/
- if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
- {
- Error_Handler();
- }
+void SystemClock_ReConfig(uint8_t mode)
+{
+ SystemClock_MSI_ON();
+
+ switch (mode)
+ {
+ case PM_RUN_MODE_HIGH_SPEED:
+ case PM_RUN_MODE_NORMAL_SPEED:
+ SystemClock_80M();
+ break;
+ case PM_RUN_MODE_MEDIUM_SPEED:
+ SystemClock_24M();
+ break;
+ case PM_RUN_MODE_LOW_SPEED:
+ SystemClock_2M();
+ break;
+ default:
+ break;
+ }
+
+ // SystemClock_MSI_OFF();
}
+
+#endif
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/board.h b/bsp/stm32/stm32l475-atk-pandora/board/board.h
index 54139616c1..83886f429d 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/board.h
+++ b/bsp/stm32/stm32l475-atk-pandora/board/board.h
@@ -32,6 +32,12 @@ extern "C" {
#define HEAP_END STM32_SRAM1_END
void SystemClock_Config(void);
+void SystemClock_MSI_ON(void);
+void SystemClock_MSI_OFF(void);
+void SystemClock_80M(void);
+void SystemClock_24M(void);
+void SystemClock_2M(void);
+void SystemClock_ReConfig(uint8_t mode);
#ifdef __cplusplus
}
diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c
index 98a993b526..3e9cf56c76 100644
--- a/components/drivers/pm/pm.c
+++ b/components/drivers/pm/pm.c
@@ -19,6 +19,7 @@
static struct rt_pm _pm;
static uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE;
static struct rt_pm_notify _pm_notify;
+static uint8_t _pm_init_flag = 0;
#define RT_PM_TICKLESS_THRESH (2)
@@ -215,6 +216,9 @@ void rt_system_power_manager(void)
{
uint8_t mode;
+ if (_pm_init_flag == 0)
+ return;
+
/* CPU frequency scaling according to the runing mode settings */
_pm_frequency_scaling(&_pm);
@@ -234,6 +238,9 @@ void rt_pm_request(uint8_t mode)
rt_base_t level;
struct rt_pm *pm;
+ if (_pm_init_flag == 0)
+ return;
+
if (mode > (PM_SLEEP_MODE_MAX - 1))
return;
@@ -256,6 +263,9 @@ void rt_pm_release(uint8_t mode)
rt_ubase_t level;
struct rt_pm *pm;
+ if (_pm_init_flag == 0)
+ return;
+
if (mode > (PM_SLEEP_MODE_MAX - 1))
return;
@@ -423,6 +433,9 @@ int rt_pm_run_enter(uint8_t mode)
rt_base_t level;
struct rt_pm *pm;
+ if (_pm_init_flag == 0)
+ return -RT_EIO;
+
if (mode > PM_RUN_MODE_MAX)
return -RT_EINVAL;
@@ -486,6 +499,8 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
pm->device_pm = RT_NULL;
pm->device_pm_number = 0;
+
+ _pm_init_flag = 1;
}
#ifdef RT_USING_FINSH
diff --git a/examples/pm/wakeup_app.c b/examples/pm/wakeup_app.c
new file mode 100644
index 0000000000..0d4c42a997
--- /dev/null
+++ b/examples/pm/wakeup_app.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-09 Zero-Free first implementation
+ */
+
+#include <board.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef RT_USING_PM
+
+#define WAKEUP_EVENT_BUTTON (1 << 0)
+#define PIN_LED_R GET_PIN(E, 7)
+#define WAKEUP_PIN GET_PIN(C, 13)
+#define WAKEUP_APP_THREAD_STACK_SIZE 1024
+
+static rt_event_t wakeup_event;
+
+static void wakeup_callback(void *args)
+{
+ rt_event_send(wakeup_event, WAKEUP_EVENT_BUTTON);
+}
+
+static void wakeup_init(void)
+{
+ rt_pin_mode(WAKEUP_PIN, PIN_MODE_INPUT_PULLUP);
+ rt_pin_attach_irq(WAKEUP_PIN, PIN_IRQ_MODE_FALLING, wakeup_callback, RT_NULL);
+ rt_pin_irq_enable(WAKEUP_PIN, 1);
+}
+
+static void wakeup_app_entry(void *parameter)
+{
+ wakeup_init();
+ rt_pm_request(PM_SLEEP_MODE_DEEP);
+
+ while (1)
+ {
+ if (rt_event_recv(wakeup_event,
+ WAKEUP_EVENT_BUTTON,
+ RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
+ RT_WAITING_FOREVER, RT_NULL) == RT_EOK)
+ {
+ rt_pm_request(PM_SLEEP_MODE_NONE);
+
+ rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
+ rt_pin_write(PIN_LED_R, 0);
+ rt_thread_delay(rt_tick_from_millisecond(500));
+ rt_pin_write(PIN_LED_R, 1);
+
+ rt_pm_release(PM_SLEEP_MODE_NONE);
+ }
+ }
+}
+
+static int wakeup_app(void)
+{
+ rt_thread_t tid;
+
+ wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_FIFO);
+ RT_ASSERT(wakeup_event != RT_NULL);
+
+ tid = rt_thread_create("wakeup_app", wakeup_app_entry, RT_NULL,
+ WAKEUP_APP_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
+ RT_ASSERT(tid != RT_NULL);
+
+ rt_thread_startup(tid);
+
+ return 0;
+}
+INIT_APP_EXPORT(wakeup_app);
+
+#endif