Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/stm32: add pm support in uart, spi and i2c (f4) #7787

Merged
merged 4 commits into from
Mar 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cpu/stm32_common/include/periph_cpu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down
4 changes: 2 additions & 2 deletions cpu/stm32_common/periph/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ 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 */
PWR->CSR |= PWR_CSR_EWUP;
/* 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);
Expand Down
9 changes: 9 additions & 0 deletions cpu/stm32_common/periph/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand All @@ -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]);
}

Expand Down
16 changes: 14 additions & 2 deletions cpu/stm32_common/periph/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions cpu/stm32f4/periph/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand Down