From c01e8629ecb4df1ae929a856b0b38625dea3e1a1 Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Mon, 23 Oct 2017 11:36:18 +0200 Subject: [PATCH 1/4] cpu/stm32_common: add PM modes --- cpu/stm32_common/include/periph_cpu_common.h | 8 ++++++++ cpu/stm32_common/periph/pm.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cpu/stm32_common/include/periph_cpu_common.h b/cpu/stm32_common/include/periph_cpu_common.h index 31e454ddd9e3..95fa6df5927b 100644 --- a/cpu/stm32_common/include/periph_cpu_common.h +++ b/cpu/stm32_common/include/periph_cpu_common.h @@ -80,6 +80,14 @@ extern "C" { #if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) \ || defined(CPU_FAM_STM32F4) || defined(DOXYGEN) #define PM_NUM_MODES (2U) + +/** + * @name Power modes + * @{ + */ +#define STM32_PM_STOP (1U) +#define STM32_PM_STANDBY (0U) +/** @} */ #endif /** diff --git a/cpu/stm32_common/periph/pm.c b/cpu/stm32_common/periph/pm.c index c3a1339dbd42..82caa6e87968 100644 --- a/cpu/stm32_common/periph/pm.c +++ b/cpu/stm32_common/periph/pm.c @@ -49,7 +49,7 @@ void pm_set(unsigned mode) * others... /KS */ #if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) switch (mode) { - case 0: + 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); /* Enable WKUP pin to use for wakeup from standby mode */ @@ -57,7 +57,7 @@ void pm_set(unsigned mode) /* Set SLEEPDEEP bit of system control block */ deep = 1; break; - case 1: /* STM Stop mode */ + case STM32_PM_STOP: /* Clear PDDS and LPDS bits to enter stop mode on */ /* deepsleep with voltage regulator on */ PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS); From 1aee2f1f141d01ba2986206d86a0d12a1c9da197 Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Mon, 23 Oct 2017 11:36:52 +0200 Subject: [PATCH 2/4] cpu/stm32_common: add pm support in uart driver --- cpu/stm32_common/periph/uart.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cpu/stm32_common/periph/uart.c b/cpu/stm32_common/periph/uart.c index f5e76ae22639..2c67d35d79c1 100644 --- a/cpu/stm32_common/periph/uart.c +++ b/cpu/stm32_common/periph/uart.c @@ -30,6 +30,7 @@ #include "assert.h" #include "periph/uart.h" #include "periph/gpio.h" +#include "pm_layered.h" #define RXENABLE (USART_CR1_RE | USART_CR1_RXNEIE) @@ -85,7 +86,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) #endif /* enable the clock */ - periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask); + uart_poweron(uart); /* reset UART configuration -> defaults to 8N1 mode */ dev(uart)->CR1 = 0; @@ -147,13 +148,24 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len) void uart_poweron(uart_t uart) { assert(uart < UART_NUMOF); +#ifdef STM32_PM_STOP + if (isr_ctx[uart].rx_cb) { + pm_block(STM32_PM_STOP); + } +#endif periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask); } void uart_poweroff(uart_t uart) { assert(uart < UART_NUMOF); - periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask); + + periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcc_mask); +#ifdef STM32_PM_STOP + if (isr_ctx[uart].rx_cb) { + pm_unblock(STM32_PM_STOP); + } +#endif } static inline void irq_handler(uart_t uart) From 34e8609f2c4f589b8cd8d922a8f77abec98c39cb Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Mon, 23 Oct 2017 11:37:01 +0200 Subject: [PATCH 3/4] cpu/stm32_common: add pm support in spi driver --- cpu/stm32_common/periph/spi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cpu/stm32_common/periph/spi.c b/cpu/stm32_common/periph/spi.c index 843ed8743912..9cc5fc2a5ea7 100644 --- a/cpu/stm32_common/periph/spi.c +++ b/cpu/stm32_common/periph/spi.c @@ -30,6 +30,7 @@ #include "mutex.h" #include "assert.h" #include "periph/spi.h" +#include "pm_layered.h" /** * @brief Number of bits to shift the BR value in the CR1 register @@ -119,6 +120,10 @@ int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) { /* lock bus */ mutex_lock(&locks[bus]); +#ifdef STM32_PM_STOP + /* block STOP mode */ + pm_block(STM32_PM_STOP); +#endif /* enable SPI device clock */ periph_clk_en(spi_config[bus].apbbus, spi_config[bus].rccmask); /* enable device */ @@ -140,6 +145,10 @@ void spi_release(spi_t bus) dev(bus)->CR1 = 0; dev(bus)->CR2 &= ~(SPI_CR2_SSOE); periph_clk_dis(spi_config[bus].apbbus, spi_config[bus].rccmask); +#ifdef STM32_PM_STOP + /* unblock STOP mode */ + pm_unblock(STM32_PM_STOP); +#endif mutex_unlock(&locks[bus]); } From 857b44a9751c51cc23354596eda3abf01f7f8bff Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Mon, 23 Oct 2017 11:37:19 +0200 Subject: [PATCH 4/4] cpu/stm32f4: add pm support in i2c driver --- cpu/stm32f4/periph/i2c.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cpu/stm32f4/periph/i2c.c b/cpu/stm32f4/periph/i2c.c index be3a2294e257..d15f915c3e6e 100644 --- a/cpu/stm32f4/periph/i2c.c +++ b/cpu/stm32f4/periph/i2c.c @@ -32,6 +32,7 @@ #include "mutex.h" #include "periph_conf.h" #include "periph/i2c.h" +#include "pm_layered.h" #define ENABLE_DEBUG (0) #include "debug.h" @@ -227,6 +228,8 @@ int i2c_acquire(i2c_t dev) return -1; } mutex_lock(&locks[dev]); + /* block STOP mode */ + pm_block(STM32_PM_STOP); return 0; } @@ -235,6 +238,8 @@ int i2c_release(i2c_t dev) if (dev >= I2C_NUMOF) { return -1; } + /* unblock STOP mode */ + pm_unblock(STM32_PM_STOP); mutex_unlock(&locks[dev]); return 0; }