diff --git a/cpu/stm32_common/include/periph_cpu_common.h b/cpu/stm32_common/include/periph_cpu_common.h index ef036dd564..c32bcc4b87 100644 --- a/cpu/stm32_common/include/periph_cpu_common.h +++ b/cpu/stm32_common/include/periph_cpu_common.h @@ -75,11 +75,15 @@ extern "C" { /** @} */ /** - * @brief Number of usable low power modes + * @name PM definitions + * @{ */ #if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \ defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32L0) || \ defined(CPU_FAM_STM32L1) || defined(DOXYGEN) +/** + * @brief Number of usable low power modes + */ #define PM_NUM_MODES (2U) /** @@ -89,7 +93,15 @@ extern "C" { #define STM32_PM_STOP (1U) #define STM32_PM_STANDBY (0U) /** @} */ + +#ifndef PM_EWUP_CONFIG +/** + * @brief Wake-up pins configuration (CSR register) + */ +#define PM_EWUP_CONFIG (0U) #endif +#endif +/** @} */ /** * @brief Available peripheral buses diff --git a/cpu/stm32_common/periph/pm.c b/cpu/stm32_common/periph/pm.c index 0fceee1b9b..3267146695 100644 --- a/cpu/stm32_common/periph/pm.c +++ b/cpu/stm32_common/periph/pm.c @@ -2,6 +2,7 @@ * Copyright (C) 2016 Kaspar Schleiser * 2015 Freie Universität Berlin * 2015 Engineering-Spirit + * 2017-2019 OTA keys S.A. * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -19,17 +20,14 @@ * @author Nick v. IJzendoorn * @author Kaspar Schleiser * @author Fabian Nack + * @author Vincent Dupont * * @} */ #include "irq.h" #include "periph/pm.h" -#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32L0) || \ - defined(CPU_FAM_STM32L1) #include "stmclk.h" -#endif #define ENABLE_DEBUG (0) #include "debug.h" @@ -40,81 +38,64 @@ * * Available values can be found in reference manual, PWR section, register CR. */ -#define PM_STOP_CONFIG (PWR_CR_LPDS | PWR_CR_FPDS) +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) +#define PM_STOP_CONFIG (PWR_CR_LPSDSR | PWR_CR_ULP) +#else +#define PM_STOP_CONFIG (PWR_CR_LPDS | PWR_CR_FPDS) +#endif +#endif + +#ifndef PM_STANDBY_CONFIG +/** + * @brief Define config flags for standby mode + * + * Available values can be found in reference manual, PWR section, register CR. + */ +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) +#define PM_STANDBY_CONFIG (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF | PWR_CR_ULP) +#else +#define PM_STANDBY_CONFIG (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF) +#endif #endif void pm_set(unsigned mode) { - int deep = 0; + int deep; -/* I just copied it from stm32f1/2/4, but I suppose it would work for the - * others... /KS */ -#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32L0) || \ - defined(CPU_FAM_STM32L1) switch (mode) { +#ifdef STM32_PM_STANDBY case STM32_PM_STANDBY: - /* Set PDDS to enter standby mode on deepsleep and clear flags */ - PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF); + PWR->CR &= ~(PM_STOP_CONFIG | PM_STANDBY_CONFIG); + PWR->CR |= PM_STANDBY_CONFIG; /* Enable WKUP pin to use for wakeup from standby mode */ -#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) - /* Enable Ultra Low Power mode */ - PWR->CR |= PWR_CR_ULP; - - PWR->CSR |= PWR_CSR_EWUP1; -#if !defined(CPU_LINE_STM32L053xx) - /* STM32L053 only have 2 wake pins */ - PWR->CSR |= PWR_CSR_EWUP3; -#endif -#else - PWR->CSR |= PWR_CSR_EWUP; -#endif + PWR->CSR |= PM_EWUP_CONFIG; /* Set SLEEPDEEP bit of system control block */ deep = 1; break; - case STM32_PM_STOP: -#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) - /* Clear Wakeup flag */ - PWR->CR |= PWR_CR_CWUF; - /* Clear PDDS to enter stop mode on */ - PWR->CR &= ~(PWR_CR_PDDS); - /* Regulator in LP mode */ - PWR->CR |= PWR_CR_LPSDSR; - - /* Enable Ultra Low Power mode*/ - PWR->CR |= PWR_CR_ULP; -#else - /* Clear PDDS and LPDS bits to enter stop mode on */ - /* deepsleep with voltage regulator on */ - PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS); - PWR->CR |= PM_STOP_CONFIG; #endif +#ifdef STM32_PM_STOP + case STM32_PM_STOP: + PWR->CR &= ~(PM_STOP_CONFIG | PM_STANDBY_CONFIG); + PWR->CR |= PM_STOP_CONFIG; /* Set SLEEPDEEP bit of system control block */ deep = 1; break; +#endif + default: + deep = 0; + break; } -#else - (void) mode; -#endif cortexm_sleep(deep); -#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32L0) || \ - defined(CPU_FAM_STM32L1) if (deep) { /* Re-init clock after STOP */ stmclk_init_sysclk(); } -#endif } -#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32L0) || \ - defined(CPU_FAM_STM32L1) void pm_off(void) { irq_disable(); pm_set(0); } -#endif