summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorthread-liu <[email protected]>2020-12-05 11:53:22 +0800
committerthread-liu <[email protected]>2020-12-05 11:54:17 +0800
commit8880e751f216a0b852bc3cfe132f84df59ab752d (patch)
tree941aa1977979996665dcd943f01c52c7386ad518 /bsp
parent6d8dbb6756a17dcb4917f093138336a12bdd7aeb (diff)
[add] low power and lptim driver.
Diffstat (limited to 'bsp')
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c2
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/Kconfig16
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/SConscript6
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c163
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c202
5 files changed, 388 insertions, 1 deletions
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
index 1958e2e516..739e195f39 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
@@ -297,7 +297,7 @@ void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef* hlptim)
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
- PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_PCLK1;
+ PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
index e276e98a08..971107f30e 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
@@ -25,6 +25,12 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_I2C3
default y
+ config BSP_USING_PWR
+ bool "Enable PM (power control)"
+ select BSP_USING_LPTIM
+ select BSP_USING_LPTIM1
+ default n
+
config BSP_USING_NAND
bool "Enable FMC (MT29F8G08ABACAH4)"
select RT_USING_FMC
@@ -181,6 +187,16 @@ menu "On-chip Peripheral Drivers"
default n
endif
+ menuconfig BSP_USING_LPTIM
+ bool "Enable lptimer"
+ default n
+ select RT_USING_LPTIMER
+ if BSP_USING_LPTIM
+ config BSP_USING_LPTIM1
+ bool "Enable LPTIM1"
+ default n
+ endif
+
menuconfig BSP_USING_PWM
bool "Enable pwm"
default n
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
index 0fc2c5a919..b3fd565887 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
@@ -64,6 +64,12 @@ if GetDepend(['BSP_USING_EXTI']):
if GetDepend(['BSP_USING_RNG']) or GetDepend(['BSP_USING_HASH']) or GetDepend(['BSP_USING_CRC']) or GetDepend(['BSP_USING_CRYP']):
src += Glob('ports/crypto_sample.c')
+if GetDepend(['BSP_USING_PWR']):
+ src += Glob('ports/drv_pwr.c')
+
+if GetDepend(['BSP_USING_LPTIM1']):
+ src += Glob('ports/drv_lptim.c')
+
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c
new file mode 100644
index 0000000000..195345c19d
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu first version
+ */
+
+#include <board.h>
+
+#ifdef BSP_USING_LPTIM
+#include "drv_config.h"
+#include <string.h>
+#include <stdlib.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.lptimer"
+#include <drv_log.h>
+
+#define LED5_PIN GET_PIN(D, 9)
+LPTIM_HandleTypeDef hlptim1;
+
+extern int lptim_stop(void);
+
+void LPTIM1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_LPTIM_IRQHandler(&hlptim1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
+{
+ if(hlptim->Instance == LPTIM1)
+ {
+ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9);
+ }
+
+#if defined(BSP_USING_PWR)
+ /* All level of ITs can interrupt */
+ __set_BASEPRI(0U);
+
+ lptim_stop();
+ rt_kprintf("system returns to normal!\n");
+#endif
+}
+
+static int lptim_control(uint8_t pre_value)
+{
+ if(pre_value > 7)
+ {
+ pre_value = 7;
+ }
+ hlptim1.Instance->CFGR &= ~(7 << 9); /* clear PRESC[2:0] */
+ hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0] */
+ rt_kprintf("set lptim pre value [0x%x] success!\n", pre_value);
+
+ return RT_EOK;
+}
+
+int lptim_start(void)
+{
+ /* ### Start counting in interrupt mode ############################# */
+ if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 32767) != HAL_OK)
+ {
+ LOG_D("lptim1 start counting failed!\n");
+ return -RT_ERROR;
+ }
+
+ LOG_D("lptim1 start counting success!\n");
+
+ return RT_EOK;
+}
+
+int lptim_stop(void)
+{
+ if (HAL_LPTIM_Counter_Stop_IT(&hlptim1) != HAL_OK)
+ {
+ LOG_D("lptim1 stop failed!\n");
+ return -RT_ERROR;
+ }
+
+ LOG_D("lptim1 stop counting success!\n");
+
+ return RT_EOK;
+}
+
+int lptim_init(void)
+{
+ rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
+
+ hlptim1.Instance = LPTIM1;
+ hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
+ hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV8;
+ hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
+ hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
+ hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
+ hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
+ hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
+ hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
+ hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
+ hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
+ if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
+ {
+ LOG_D("lptim init failed!\n");
+ return -RT_ERROR;
+ }
+ LOG_D("lptim init success!\n");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(lptim_init);
+
+static int lptim_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "start"))
+ {
+ lptim_start();
+ return RT_EOK;
+ }
+ else if (!strcmp(argv[1], "stop"))
+ {
+ lptim_stop();
+ return RT_EOK;
+ }
+ else if (!strcmp(argv[1], "set"))
+ {
+ if (argc > 2)
+ {
+ lptim_control(atoi(argv[2]));
+ return RT_EOK;
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+_exit:
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("lptim_sample start - start lptim, the LED5 will start blink\n");
+ rt_kprintf("lptim_sample stop - stop lptim, the LED5 will stop blink\n");
+ rt_kprintf("lptim_sample set - set the lptim prescaler to change LED5 blink frquency, lptim_sample set [0 - 7]\n");
+ }
+
+ return -RT_ERROR;
+}
+MSH_CMD_EXPORT(lptim_sample, low power timer sample);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c
new file mode 100644
index 0000000000..3aac57603d
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#include "board.h"
+//#define DRV_DEBUG
+#define LOG_TAG "drv.pwr"
+#include <drv_log.h>
+
+extern int lptim_start(void);
+extern int lptim_stop(void);
+
+static RCC_ClkInitTypeDef RCC_ClkInit = {0};
+
+#define __WAIT_EVENT_TIMEOUT(__CONDITION__, __TIMEOUT_VAL__) \
+ do { \
+ __IO uint32_t count = __TIMEOUT_VAL__ * (SystemCoreClock / 20U / 1000U); \
+ do \
+ { \
+ if (count-- == 0U) \
+ { \
+ return HAL_TIMEOUT; \
+ } \
+ } \
+ while (__CONDITION__ == 0U); \
+ } while(0)
+
+/* Back up clock tree */
+static void backup_cm4_clocks(void)
+{
+ rt_uint32_t *pFLatency = NULL;
+
+ /* Back up MCU clock configuration */
+ HAL_RCC_GetClockConfig(&RCC_ClkInit, pFLatency);
+}
+
+/* Restore the CM4 clock source muxer and the CM4 prescaler. */
+rt_err_t restore_cm4_clock(void)
+{
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Enable PLL3 if needed */
+ if (RCC_ClkInit.MCUInit.MCU_Clock == RCC_MCUSSOURCE_PLL3)
+ {
+ /* Enable PLL3 */
+ __HAL_RCC_PLL3_ENABLE();
+
+ /* Wait till PLL3 is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY), CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Enable PLL3 outputs */
+ __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVP | RCC_PLL3_DIVQ | RCC_PLL3_DIVR);
+ }
+
+ /* Configure MCU clock only */
+ __HAL_RCC_MCU_SOURCE(RCC_ClkInit.MCUInit.MCU_Clock);
+
+ /* Wait till MCU is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUSSRCRDY),
+ CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Reconfigure Systick */
+ if (HAL_InitTick(uwTickPrio) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ /* Set MCU division factor */
+ __HAL_RCC_MCU_DIV(RCC_ClkInit.MCUInit.MCU_Div);
+
+ /* Wait till MCUDIV is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUDIVRDY),
+ CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Reconfigure Systick */
+ if (HAL_InitTick(uwTickPrio) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+void RCC_WAKEUP_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_RCC_WAKEUP_IRQHandler();
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_RCC_WAKEUP_Callback()
+{
+ if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOP) == 1U)
+ {
+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
+ }
+
+ restore_cm4_clock();
+ /* All level of ITs can interrupt */
+ __set_BASEPRI(0U);
+
+ rt_kprintf("system exit stop mode success!\n");
+}
+
+static void enter_sleep_mode(void)
+{
+ __set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
+
+ lptim_start();
+
+ HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
+}
+
+static void enter_stop_mode(void)
+{
+ /*
+ * Only the IT with the highest priority (0 value) can interrupt.
+ * RCC_WAKEUP_IRQn IT is intended to have the highest priority and to be the
+ * only one IT having this value
+ * RCC_WAKEUP_IRQn is generated only when RCC is completely resumed from
+ * CSTOP (protection mechanism)
+ */
+ __set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
+
+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
+ backup_cm4_clocks();
+ HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
+}
+
+static void pm_wackup_key_init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ HAL_NVIC_SetPriority(EXTI13_IRQn, 0x01, 0);
+ HAL_NVIC_EnableIRQ(EXTI13_IRQn);
+}
+
+int drv_pm_hw_init(void)
+{
+ pm_wackup_key_init();
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(drv_pm_hw_init);
+
+static int pwr_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!rt_strcmp(argv[1], "stop"))
+ {
+ rt_kprintf("system will enter stop mode! you can press USER2 button to exit this mode\n");
+ enter_stop_mode();
+ return RT_EOK;
+
+ }
+ else if (!rt_strcmp(argv[1], "sleep"))
+ {
+ rt_kprintf("system will enter sleep mode! lptim1 will wake up the system\n");
+ enter_sleep_mode();
+ return RT_EOK;
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+_exit:
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("pwr_sample stop - system enter stop mode\n");
+ rt_kprintf("pwr_sample sleep - system enter sleep mode\n");
+ }
+
+ return -RT_ERROR;
+}
+MSH_CMD_EXPORT(pwr_sample, enter low power mode sample);