From 940b80243f023576151425652ed4353781600c41 Mon Sep 17 00:00:00 2001 From: fjmolinas Date: Mon, 8 Apr 2019 22:40:07 +0200 Subject: [PATCH 1/2] cpu/stm32_common: minimize consumption for STM32F0/2/3/4/7 - With this PR, On start up all GPIOs are configured as AIN. For stm32l0/4 this is done by default. Doing this saves the consumption of the input Schmitt trigger in STOP mode which can reduce the consumption in at least 70% from current master. --- cpu/stm32_common/cpu_init.c | 74 +++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/cpu/stm32_common/cpu_init.c b/cpu/stm32_common/cpu_init.c index c11866217a5a..4ebce816ee89 100644 --- a/cpu/stm32_common/cpu_init.c +++ b/cpu/stm32_common/cpu_init.c @@ -26,6 +26,8 @@ * @author Víctor Ariño * @author Kaspar Schleiser * @author Vincent Dupont + * @author Oleg Artamonov + * @author Francisco Molina * * @} */ @@ -41,6 +43,73 @@ #define BIT_APB_PWREN RCC_APB1ENR_PWREN #endif +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ + defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) + +#define STM32_CPU_MAX_GPIOS (12U) + +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) +#define GPIO_CLK (AHB) +#define GPIO_CLK_ENR (RCC->AHBENR) +#define GPIO_CLK_ENR_MASK (0xFFFF0000) +#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) +#define GPIO_CLK (AHB1) +#define GPIO_CLK_ENR (RCC->AHB1ENR) +#define GPIO_CLK_ENR_MASK (0x0000FFFF) +#endif + +#ifndef DISABLE_JTAG +#define DISABLE_JTAG 0 +#endif + +/** + * @brief Initialize gpio to AIN + * + * stm32f need to have all there pins initialized to AIN so the consumption + * of the input Schmitt trigger is saved when running in STOP mode. + * + * @see https://comm.eefocus.com/media/download/index/id-1013834 + */ +static void _gpio_init_ain(void) +{ + uint32_t ahb_gpio_clocks; + + /* enable GPIO clock and save GPIO clock configuration */ + ahb_gpio_clocks = GPIO_CLK_ENR & GPIO_CLK_ENR_MASK; + periph_clk_en(GPIO_CLK, GPIO_CLK_ENR_MASK); + + /* switch all GPIOs to AIN mode to minimize power consumption */ + for (uint8_t i = 0; i < STM32_CPU_MAX_GPIOS; i++) { + GPIO_TypeDef *port; + port = (GPIO_TypeDef *)(GPIOA_BASE + i*(GPIOB_BASE - GPIOA_BASE)); + if (IS_GPIO_ALL_INSTANCE(port)) { + if (!DISABLE_JTAG) { + switch (i) { + /* preserve JTAG pins on PORTA and PORTB */ + case 0: + port->MODER = 0xABFFFFFF; + break; + case 1: + port->MODER = 0xFFFFFEBF; + break; + default: + port->MODER = 0xFFFFFFFF; + break; + } + } + else { + port->MODER = 0xFFFFFFFF; + } + } + } + + /* restore GPIO clocks */ + periph_clk_en(GPIO_CLK, ahb_gpio_clocks); +} +#endif + void cpu_init(void) { /* initialize the Cortex-M core */ @@ -49,6 +118,11 @@ void cpu_init(void) periph_clk_en(APB1, BIT_APB_PWREN); /* initialize the system clock as configured in the periph_conf.h */ stmclk_init_sysclk(); +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ + defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) + _gpio_init_ain(); +#endif #ifdef MODULE_PERIPH_DMA /* initialize DMA streams */ dma_init(); From 1b7a8611d8e9c90c1a505294b8a95acafbe3858b Mon Sep 17 00:00:00 2001 From: francisco Date: Wed, 3 Jul 2019 16:38:18 +0200 Subject: [PATCH 2/2] cpu/stm32_common: minimize consumption for STM32F1 - With this PR all GPIOs are set as AIN on start up. --- cpu/stm32_common/cpu_init.c | 39 +++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/cpu/stm32_common/cpu_init.c b/cpu/stm32_common/cpu_init.c index 4ebce816ee89..e64ba3f38b57 100644 --- a/cpu/stm32_common/cpu_init.c +++ b/cpu/stm32_common/cpu_init.c @@ -43,9 +43,9 @@ #define BIT_APB_PWREN RCC_APB1ENR_PWREN #endif -#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ - defined(CPU_FAM_STM32F7) +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F1) || \ + defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F3) || \ + defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32F7) #define STM32_CPU_MAX_GPIOS (12U) @@ -58,6 +58,10 @@ #define GPIO_CLK (AHB1) #define GPIO_CLK_ENR (RCC->AHB1ENR) #define GPIO_CLK_ENR_MASK (0x0000FFFF) +#elif defined(CPU_FAM_STM32F1) +#define GPIO_CLK (APB2) +#define GPIO_CLK_ENR (RCC->APB2ENR) +#define GPIO_CLK_ENR_MASK (0x000001FC) #endif #ifndef DISABLE_JTAG @@ -86,6 +90,23 @@ static void _gpio_init_ain(void) port = (GPIO_TypeDef *)(GPIOA_BASE + i*(GPIOB_BASE - GPIOA_BASE)); if (IS_GPIO_ALL_INSTANCE(port)) { if (!DISABLE_JTAG) { +#if defined(CPU_FAM_STM32F1) + switch (i) { + /* preserve JTAG pins on PORTA and PORTB */ + case 0: + port->CR[0] = GPIO_CRL_CNF; + port->CR[1] = GPIO_CRH_CNF & 0x000FFFFF; + break; + case 1: + port->CR[0] = GPIO_CRL_CNF & 0xFFF00FFF; + port->CR[1] = GPIO_CRH_CNF; + break; + default: + port->CR[0] = GPIO_CRL_CNF; + port->CR[1] = GPIO_CRH_CNF; + break; + } +#else /* ! defined(CPU_FAM_STM32F1) */ switch (i) { /* preserve JTAG pins on PORTA and PORTB */ case 0: @@ -98,9 +119,15 @@ static void _gpio_init_ain(void) port->MODER = 0xFFFFFFFF; break; } +#endif /* defined(CPU_FAM_STM32F1) */ } else { +#if defined(CPU_FAM_STM32F1) + port->CR[0] = GPIO_CRL_CNF; + port->CR[1] = GPIO_CRH_CNF; +#else port->MODER = 0xFFFFFFFF; +#endif } } } @@ -118,9 +145,9 @@ void cpu_init(void) periph_clk_en(APB1, BIT_APB_PWREN); /* initialize the system clock as configured in the periph_conf.h */ stmclk_init_sysclk(); -#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ - defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ - defined(CPU_FAM_STM32F7) +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F1) || \ + defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F3) || \ + defined(CPU_FAM_STM32F4) || defined(CPU_FAM_STM32F7) _gpio_init_ain(); #endif #ifdef MODULE_PERIPH_DMA