1 /* 2 * Copyright (c) 2021 Fabio Baltieri 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #include <zephyr/kernel.h> 7 #include <zephyr/pm/pm.h> 8 #include <soc.h> 9 #include <zephyr/init.h> 10 11 #include <stm32l0xx_ll_utils.h> 12 #include <stm32l0xx_ll_bus.h> 13 #include <stm32l0xx_ll_cortex.h> 14 #include <stm32l0xx_ll_pwr.h> 15 #include <stm32l0xx_ll_rcc.h> 16 #include <stm32l0xx_ll_system.h> 17 #include <clock_control/clock_stm32_ll_common.h> 18 #include <zephyr/drivers/clock_control/stm32_clock_control.h> 19 20 #include <zephyr/logging/log.h> 21 LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); 22 23 /* Select MSI as wake-up system clock if configured, HSI otherwise */ 24 #if STM32_SYSCLK_SRC_MSI 25 #define RCC_STOP_WAKEUPCLOCK_SELECTED LL_RCC_STOP_WAKEUPCLOCK_MSI 26 #else 27 #define RCC_STOP_WAKEUPCLOCK_SELECTED LL_RCC_STOP_WAKEUPCLOCK_HSI 28 #endif 29 30 /* Invoke Low Power/System Off specific Tasks */ pm_state_set(enum pm_state state,uint8_t substate_id)31void pm_state_set(enum pm_state state, uint8_t substate_id) 32 { 33 ARG_UNUSED(substate_id); 34 35 switch (state) { 36 case PM_STATE_SUSPEND_TO_IDLE: 37 LL_RCC_SetClkAfterWakeFromStop(RCC_STOP_WAKEUPCLOCK_SELECTED); 38 LL_PWR_ClearFlag_WU(); 39 LL_PWR_SetPowerMode(LL_PWR_MODE_STOP); 40 LL_PWR_SetRegulModeLP(LL_PWR_REGU_LPMODES_LOW_POWER); 41 LL_LPM_EnableDeepSleep(); 42 k_cpu_idle(); 43 break; 44 default: 45 LOG_DBG("Unsupported power state %u", state); 46 break; 47 } 48 } 49 50 /* Handle SOC specific activity after Low Power Mode Exit */ pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)51void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) 52 { 53 ARG_UNUSED(substate_id); 54 55 switch (state) { 56 case PM_STATE_SUSPEND_TO_IDLE: 57 LL_LPM_DisableSleepOnExit(); 58 LL_LPM_EnableSleep(); 59 LL_PWR_SetRegulModeLP(LL_PWR_REGU_LPMODES_MAIN); 60 61 /* Restore the clock setup. */ 62 stm32_clock_control_init(NULL); 63 break; 64 default: 65 LOG_DBG("Unsupported power substate-id %u", state); 66 break; 67 } 68 69 /* 70 * System is now in active mode. Reenable interrupts which were 71 * disabled when OS started idling code. 72 */ 73 irq_unlock(0); 74 } 75