diff --git a/cpu/stm32_common/cpu_init.c b/cpu/stm32_common/cpu_init.c index dd79c65c10899..11e4a6f784b41 100644 --- a/cpu/stm32_common/cpu_init.c +++ b/cpu/stm32_common/cpu_init.c @@ -50,43 +50,10 @@ 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_STM32L1) - uint32_t ahb_gpio_clocks; - GPIO_TypeDef *port; - - /* enable GPIO clock and save GPIO clock configuration */ - ahb_gpio_clocks = RCC->AHBENR & 0xFF; - periph_clk_en(AHB, 0xFF); - - /* switch all GPIOs to AIN mode to minimize power consumption */ - /* can't be more than 12 ports on STM32L1 */ - for (int i = 0; i < 12; i++) { - port = (GPIO_TypeDef *)(GPIOA_BASE + i*(GPIOB_BASE - GPIOA_BASE)); - if (IS_GPIO_ALL_INSTANCE(port)) { -#if !defined (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; -#endif - } - else { - break; - } - /* restore GPIO clock */ - periph_clk_en(AHB, ((RCC->AHBENR & ~((uint32_t)0xFF)) | ahb_gpio_clocks)); - } +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ + defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L1) + gpio_pm_init_ain(); #endif #ifdef MODULE_PERIPH_DMA /* initialize DMA streams */ diff --git a/cpu/stm32_common/include/periph_cpu_common.h b/cpu/stm32_common/include/periph_cpu_common.h index 19e1bc060ac3f..61be2b2b3fecc 100644 --- a/cpu/stm32_common/include/periph_cpu_common.h +++ b/cpu/stm32_common/include/periph_cpu_common.h @@ -601,6 +601,20 @@ void gpio_init_af(gpio_t pin, gpio_af_t af); */ void gpio_init_analog(gpio_t pin); + +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ + defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L1) +/** + * @brief Initialize gpio to AIN + * + * stm32l1 and stm32f need to have all there pins initialized to AIN to achieve + * lowest power consumption (this makes the difference between 500uA and 1.7uA + * in STOP_MODE). + */ +void gpio_pm_init_ain(void); +#endif + #ifdef MODULE_PERIPH_DMA /** * @brief DMA stream not defined diff --git a/cpu/stm32_common/periph/gpio.c b/cpu/stm32_common/periph/gpio.c index 6a2e6a662553a..6622adb4227bc 100644 --- a/cpu/stm32_common/periph/gpio.c +++ b/cpu/stm32_common/periph/gpio.c @@ -257,6 +257,70 @@ void isr_exti(void) } #endif /* MODULE_PERIPH_GPIO_IRQ */ + +#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F2) || \ + defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) || defined(CPU_FAM_STM32L1) + +#define AHBENR_LOWER_MASK (0x0000FFFF) +#define AHBENR_UPPER_MASK (0xFFFF0000) +#define AHB1ENR_LOWER_MASK (0x0000FFFF) + +#define STM32_CPU_MAX_GPIOS (12U) + +void gpio_pm_init_ain(void) +{ + uint32_t ahb_gpio_clocks; + + /* enable GPIO clock and save GPIO clock configuration */ +#if defined(CPU_FAM_STM32L1) + ahb_gpio_clocks = RCC->AHBENR & AHBENR_LOWER_MASK; + periph_clk_en(AHB, AHBENR_LOWER_MASK); +#elif defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F0) + ahb_gpio_clocks = RCC->AHBENR & AHBENR_UPPER_MASK; + periph_clk_en(AHB, AHBENR_UPPER_MASK); +#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) + ahb_gpio_clocks = RCC->AHB1ENR & AHBENR_LOWER_MASK; + periph_clk_en(AHB1, AHB1ENR_LOWER_MASK); +#endif + /* 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 !defined (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; +#endif + } + else { + break; + } + } + /* restore GPIO clock */ +#if defined(CPU_FAM_STM32L1) + periph_clk_en(AHB, ((RCC->AHBENR & ~((uint32_t)AHBENR_LOWER_MASK)) | ahb_gpio_clocks)); +#elif defined(CPU_FAM_STM32F3) || defined(CPU_FAM_STM32F0) + periph_clk_en(AHB, ((RCC->AHBENR & ~((uint32_t)AHBENR_UPPER_MASK)) | ahb_gpio_clocks)); +#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \ + defined(CPU_FAM_STM32F7) + periph_clk_en(AHB1, ((RCC->AHB1ENR & ~((uint32_t)AHB1ENR_LOWER_MASK)) | ahb_gpio_clocks)); +#endif +} +#endif #else typedef int dont_be_pedantic; #endif