Skip to content

Commit

Permalink
cpu/stm32_common: minimize consumption for STM32F
Browse files Browse the repository at this point in the history
  • Loading branch information
fjmolinas committed Apr 12, 2019
1 parent f4df055 commit 676efb9
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 37 deletions.
41 changes: 4 additions & 37 deletions cpu/stm32_common/cpu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
14 changes: 14 additions & 0 deletions cpu/stm32_common/include/periph_cpu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 64 additions & 0 deletions cpu/stm32_common/periph/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 676efb9

Please sign in to comment.