1 /* 2 * Copyright (c) 2021 STMicroelectronics. 3 * Copyright (c) 2021 G-Technologies Sdn. Bhd. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 #include <zephyr/kernel.h> 8 #include <zephyr/pm/pm.h> 9 #include <soc.h> 10 #include <zephyr/init.h> 11 12 #include <stm32g0xx_ll_utils.h> 13 #include <stm32g0xx_ll_bus.h> 14 #include <stm32g0xx_ll_cortex.h> 15 #include <stm32g0xx_ll_pwr.h> 16 #include <stm32g0xx_ll_system.h> 17 #include <clock_control/clock_stm32_ll_common.h> 18 19 #include <zephyr/logging/log.h> 20 LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); 21 22 /* Invoke Low Power/System Off specific Tasks */ pm_state_set(enum pm_state state,uint8_t substate_id)23void pm_state_set(enum pm_state state, uint8_t substate_id) 24 { 25 if (state != PM_STATE_SUSPEND_TO_IDLE) { 26 LOG_DBG("Unsupported power state %u", state); 27 return; 28 } 29 30 switch (substate_id) { 31 case 1: /* this corresponds to the STOP0 mode: */ 32 /* enter STOP0 mode */ 33 LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); 34 LL_LPM_EnableDeepSleep(); 35 /* enter SLEEP mode : WFE or WFI */ 36 k_cpu_idle(); 37 break; 38 case 2: /* this corresponds to the STOP1 mode: */ 39 /* enter STOP1 mode */ 40 LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); 41 LL_LPM_EnableDeepSleep(); 42 /* enter SLEEP mode : WFE or WFI */ 43 k_cpu_idle(); 44 break; 45 default: 46 LOG_DBG("Unsupported power state substate-id %u", 47 substate_id); 48 break; 49 } 50 } 51 52 /* Handle SOC specific activity after Low Power Mode Exit */ pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)53void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) 54 { 55 if (state != PM_STATE_SUSPEND_TO_IDLE) { 56 LOG_DBG("Unsupported power substate %u", state); 57 } else { 58 switch (substate_id) { 59 case 1: /* STOP0 */ 60 __fallthrough; 61 case 2: /* STOP1 */ 62 LL_LPM_DisableSleepOnExit(); 63 /* Clear SLEEPDEEP bit */ 64 LL_LPM_EnableSleep(); 65 break; 66 default: 67 LOG_DBG("Unsupported power substate-id %u", 68 substate_id); 69 break; 70 } 71 /* need to restore the clock */ 72 stm32_clock_control_init(NULL); 73 } 74 75 /* 76 * System is now in active mode. 77 * Reenable interrupts which were disabled 78 * when OS started idling code. 79 */ 80 irq_unlock(0); 81 } 82 83 /* Initialize STM32 Power */ stm32_power_init(void)84void stm32_power_init(void) 85 { 86 87 /* enable Power clock */ 88 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); 89 } 90