Merge pull request #5090 from haukepetersen/opt_stm_clken

cpu/stm32_common: added shared periph_clk_en/dis functions
This commit is contained in:
DipSwitch 2016-03-16 23:02:20 +01:00
commit 93bce6291c
16 changed files with 185 additions and 123 deletions

View File

@ -83,16 +83,16 @@ extern "C" {
* @{ * @{
*/ */
static const uart_conf_t uart_config[] = { static const uart_conf_t uart_config[] = {
/* device, RCC mask, RX pin, TX pin, pin AF, IRQ channel, DMA stream, DMA */
{ {
USART6, /* device base register */ .dev = USART6,
RCC_APB2ENR_USART6EN, /* RCC mask */ .rcc_mask = RCC_APB2ENR_USART6EN,
GPIO_PIN(PORT_C,7), /* RX pin */ .rx_pin = GPIO_PIN(PORT_C,7),
GPIO_PIN(PORT_C,6), /* TX pin */ .tx_pin = GPIO_PIN(PORT_C,6),
GPIO_AF8, /* pin AF */ .af = GPIO_AF8,
USART6_IRQn, /* IRQ channel */ .bus = APB2,
14, /* DMA stream */ .irqn = USART6_IRQn,
5 /* DMA channel */ .dma_stream = 14,
.dma_chan = 5
}, },
}; };

View File

@ -58,9 +58,18 @@ extern "C" {
* @{ * @{
*/ */
static const timer_conf_t timer_config[] = { static const timer_conf_t timer_config[] = {
/* device, APB bus, rcc_bit */ {
{ TIM2, APB1, RCC_APB1ENR_TIM2EN, TIM2_IRQn }, .dev = TIM2,
{ TIM3, APB1, RCC_APB1ENR_TIM3EN, TIM3_IRQn } .rcc_mask = RCC_APB1ENR_TIM2EN,
.bus = APB1,
.irqn = TIM2_IRQn
},
{
.dev = TIM3,
.rcc_mask = RCC_APB1ENR_TIM3EN,
.bus = APB1,
.irqn = TIM3_IRQn
}
}; };
#define TIMER_0_ISR isr_tim2 #define TIMER_0_ISR isr_tim2

View File

@ -64,9 +64,18 @@ extern "C" {
* @{ * @{
*/ */
static const timer_conf_t timer_config[] = { static const timer_conf_t timer_config[] = {
/* device, APB bus, rcc_bit */ {
{ TIM2, APB1, RCC_APB1ENR_TIM2EN, TIM2_IRQn }, .dev = TIM2,
{ TIM3, APB1, RCC_APB1ENR_TIM3EN, TIM3_IRQn } .rcc_mask = RCC_APB1ENR_TIM2EN,
.bus = APB1,
.irqn = TIM2_IRQn
},
{
.dev = TIM3,
.rcc_mask = RCC_APB1ENR_TIM3EN,
.bus = APB1,
.irqn = TIM3_IRQn
}
}; };
#define TIMER_0_ISR isr_tim2 #define TIMER_0_ISR isr_tim2

View File

@ -129,40 +129,42 @@ extern "C" {
/** @} */ /** @} */
/** /**
* @name UART configuration * @brief UART configuration
* @{ * @{
*/ */
static const uart_conf_t uart_config[] = { static const uart_conf_t uart_config[] = {
/* device, RCC mask, RX pin, TX pin, pin AF, IRQ channel, DMA stream, DMA */
{ {
USART2, /* device base register */ .dev = USART2,
RCC_APB1ENR_USART2EN, /* RCC mask */ .rcc_mask = RCC_APB1ENR_USART2EN,
GPIO_PIN(PORT_A,3), /* RX pin */ .rx_pin = GPIO_PIN(PORT_A,3),
GPIO_PIN(PORT_A,2), /* TX pin */ .tx_pin = GPIO_PIN(PORT_A,2),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART2_IRQn, /* IRQ channel */ .bus = APB1,
6, /* DMA stream */ .irqn = USART2_IRQn,
4 /* DMA channel */ .dma_stream = 6,
.dma_chan = 4
}, },
{ {
USART1, /* device base register */ .dev = USART1,
RCC_APB2ENR_USART1EN, /* RCC mask */ .rcc_mask = RCC_APB2ENR_USART1EN,
GPIO_PIN(PORT_A,10), /* RX pin */ .rx_pin = GPIO_PIN(PORT_A,10),
GPIO_PIN(PORT_A,9), /* TX pin */ .tx_pin = GPIO_PIN(PORT_A,9),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART1_IRQn, /* IRQ channel */ .bus = APB2,
15, /* DMA stream */ .irqn = USART1_IRQn,
4 /* DMA channel */ .dma_stream = 15,
.dma_chan = 4
}, },
{ {
USART3, /* device base register */ .dev = USART3,
RCC_APB1ENR_USART3EN, /* RCC mask */ .rcc_mask = RCC_APB1ENR_USART3EN,
GPIO_PIN(PORT_D,9), /* RX pin */ .rx_pin = GPIO_PIN(PORT_D,9),
GPIO_PIN(PORT_D,8), /* TX pin */ .tx_pin = GPIO_PIN(PORT_D,8),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART3_IRQn, /* IRQ channel */ .bus = APB1,
3, /* DMA stream */ .irqn = USART3_IRQn,
4 /* DMA channel */ .dma_stream = 3,
.dma_chan = 4
}, },
}; };

View File

@ -61,9 +61,18 @@ extern "C" {
* @{ * @{
*/ */
static const timer_conf_t timer_config[] = { static const timer_conf_t timer_config[] = {
/* device, APB bus, rcc_bit */ {
{ TIM2, APB1, RCC_APB1ENR_TIM2EN, TIM2_IRQn }, .dev = TIM2,
{ TIM3, APB1, RCC_APB1ENR_TIM3EN, TIM3_IRQn } .rcc_mask = RCC_APB1ENR_TIM2EN,
.bus = APB1,
.irqn = TIM2_IRQn
},
{
.dev = TIM3,
.rcc_mask = RCC_APB1ENR_TIM3EN,
.bus = APB1,
.irqn = TIM3_IRQn
}
}; };
#define TIMER_0_ISR isr_tim2 #define TIMER_0_ISR isr_tim2

View File

@ -77,20 +77,20 @@ extern "C" {
/** @} */ /** @} */
/** /**
* @name UART configuration * @brief UART configuration
* @{ * @{
*/ */
static const uart_conf_t uart_config[] = { static const uart_conf_t uart_config[] = {
/* device, RCC mask, RX pin, TX pin, pin AF, IRQ channel, DMA stream, DMA */
{ {
USART2, /* device base register */ .dev = USART2,
RCC_APB1ENR_USART2EN, /* RCC mask */ .rcc_mask = RCC_APB1ENR_USART2EN,
GPIO_PIN(PORT_A,3), /* RX pin */ .rx_pin = GPIO_PIN(PORT_A,3),
GPIO_PIN(PORT_A,2), /* TX pin */ .tx_pin = GPIO_PIN(PORT_A,2),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART2_IRQn, /* IRQ channel */ .bus = APB1,
6, /* DMA stream */ .irqn = USART2_IRQn,
4 /* DMA channel */ .dma_stream = 6,
.dma_chan = 4
} }
}; };

View File

@ -58,9 +58,18 @@
* @{ * @{
*/ */
static const timer_conf_t timer_config[] = { static const timer_conf_t timer_config[] = {
/* device, APB bus, rcc_bit */ {
{ TIM2, APB1, RCC_APB1ENR_TIM2EN, TIM2_IRQn }, .dev = TIM2,
{ TIM3, APB1, RCC_APB1ENR_TIM3EN, TIM3_IRQn } .rcc_mask = RCC_APB1ENR_TIM2EN,
.bus = APB1,
.irqn = TIM2_IRQn
},
{
.dev = TIM3,
.rcc_mask = RCC_APB1ENR_TIM3EN,
.bus = APB1,
.irqn = TIM3_IRQn
}
}; };
#define TIMER_0_ISR isr_tim2 #define TIMER_0_ISR isr_tim2

View File

@ -78,30 +78,31 @@ extern "C" {
/** @} */ /** @} */
/** /**
* @name UART configuration * @brief UART configuration
* @{ * @{
*/ */
static const uart_conf_t uart_config[] = { static const uart_conf_t uart_config[] = {
/* device, RCC mask, RX pin, TX pin, pin AF, IRQ channel, DMA stream, DMA */
{ {
USART2, /* device base register */ .dev = USART2,
RCC_APB1ENR_USART2EN, /* RCC mask */ .rcc_mask = RCC_APB1ENR_USART2EN,
GPIO_PIN(PORT_A,3), /* RX pin */ .rx_pin = GPIO_PIN(PORT_A,3),
GPIO_PIN(PORT_A,2), /* TX pin */ .tx_pin = GPIO_PIN(PORT_A,2),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART2_IRQn, /* IRQ channel */ .bus = APB1,
6, /* DMA stream */ .irqn = USART2_IRQn,
4 /* DMA channel */ .dma_stream = 6,
.dma_chan = 4
}, },
{ {
USART3, /* device base register */ .dev = USART3,
RCC_APB1ENR_USART3EN, /* RCC mask */ .rcc_mask = RCC_APB1ENR_USART3EN,
GPIO_PIN(PORT_D,9), /* RX pin */ .rx_pin = GPIO_PIN(PORT_D,9),
GPIO_PIN(PORT_D,8), /* TX pin */ .tx_pin = GPIO_PIN(PORT_D,8),
GPIO_AF7, /* pin AF */ .af = GPIO_AF7,
USART3_IRQn, /* IRQ channel */ .bus = APB1,
3, /* DMA stream */ .irqn = USART3_IRQn,
4 /* DMA channel */ .dma_stream = 3,
.dma_chan = 4
}, },
}; };

View File

@ -1,3 +1,5 @@
MODULE = stm32_common
DIRS = periph DIRS = periph
include $(RIOTBASE)/Makefile.base include $(RIOTBASE)/Makefile.base

View File

@ -5,8 +5,8 @@ export CFLAGS += -DCPU_FAM_$(FAM)
# include common periph module # include common periph module
USEMODULE += periph_common USEMODULE += periph_common
# include stm32 common periph drivers # include stm32 common functions and stm32 common periph drivers
USEMODULE += stm32_common_periph USEMODULE += stm32_common stm32_common_periph
# export the common include directory # export the common include directory
export INCLUDES += -I$(RIOTCPU)/stm32_common/include export INCLUDES += -I$(RIOTCPU)/stm32_common/include

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_cortexm_common
* @{
*
* @file
* @brief Shared CPU specific function for the STM32 CPU family
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "periph_cpu_common.h"
void periph_clk_en(uint8_t bus, uint32_t mask)
{
if (bus == APB1) {
RCC->APB1ENR |= mask;
} else {
RCC->APB2ENR |= mask;
}
}
void periph_clk_dis(uint8_t bus, uint32_t mask)
{
if (bus == APB1) {
RCC->APB1ENR &= ~(mask);
} else {
RCC->APB2ENR &= ~(mask);
}
}

View File

@ -43,10 +43,26 @@ extern "C" {
* @brief Available peripheral buses * @brief Available peripheral buses
*/ */
enum { enum {
APB1, APB1, /**< APB1 bus */
APB2 APB2 /**< APB2 bus */
}; };
/**
* @brief Enable the given peripheral clock
*
* @param[in] bus bus the peripheral is connected to
* @param[in] mask bit in the RCC enable register
*/
void periph_clk_en(uint8_t bus, uint32_t mask);
/**
* @brief Disable the given peripheral clock
*
* @param[in] bus bus the peripheral is connected to
* @param[in] mask bit in the RCC enable register
*/
void periph_clk_dis(uint8_t bus, uint32_t mask);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -120,8 +120,8 @@ typedef struct {
*/ */
typedef struct { typedef struct {
TIM_TypeDef *dev; /**< timer device */ TIM_TypeDef *dev; /**< timer device */
uint32_t rcc_mask; /**< corresponding bit in the RCC register */
uint8_t bus; /**< APBx bus the timer is clock from */ uint8_t bus; /**< APBx bus the timer is clock from */
uint8_t rcc_bit; /**< corresponding bit in the RCC register */
uint8_t irqn; /**< global IRQ channel */ uint8_t irqn; /**< global IRQ channel */
} timer_conf_t; } timer_conf_t;

View File

@ -37,19 +37,6 @@ static inline TIM_TypeDef *dev(tim_t tim)
return timer_config[tim].dev; return timer_config[tim].dev;
} }
/**
* @brief Enable the peripheral clock for the given timer
*/
static void clk_en(tim_t tim)
{
if (timer_config[tim].bus == APB1) {
RCC->APB1ENR |= timer_config[tim].rcc_bit;
}
else {
RCC->APB2ENR |= timer_config[tim].rcc_bit;
}
}
int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
{ {
/* check if device is valid */ /* check if device is valid */
@ -62,7 +49,7 @@ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
isr_ctx[tim].arg = arg; isr_ctx[tim].arg = arg;
/* enable the peripheral clock */ /* enable the peripheral clock */
clk_en(tim); periph_clk_en(timer_config[tim].bus, timer_config[tim].rcc_mask);
/* configure the timer as upcounter in continuous mode */ /* configure the timer as upcounter in continuous mode */
dev(tim)->CR1 = 0; dev(tim)->CR1 = 0;
@ -145,7 +132,6 @@ static inline void irq_handler(tim_t tim)
isr_ctx[tim].cb(isr_ctx[tim].arg, i); isr_ctx[tim].cb(isr_ctx[tim].arg, i);
} }
} }
if (sched_context_switch_request) { if (sched_context_switch_request) {
thread_yield(); thread_yield();
} }

View File

@ -122,6 +122,7 @@ typedef struct {
gpio_t rx_pin; /**< RX pin */ gpio_t rx_pin; /**< RX pin */
gpio_t tx_pin; /**< TX pin */ gpio_t tx_pin; /**< TX pin */
gpio_af_t af; /**< alternate pin function to use */ gpio_af_t af; /**< alternate pin function to use */
uint8_t bus; /**< APB bus */
uint8_t irqn; /**< IRQ channel */ uint8_t irqn; /**< IRQ channel */
uint8_t dma_stream; /**< DMA stream used for TX */ uint8_t dma_stream; /**< DMA stream used for TX */
uint8_t dma_chan; /**< DMA channel used for TX */ uint8_t dma_chan; /**< DMA channel used for TX */

View File

@ -45,17 +45,6 @@ static inline USART_TypeDef *_dev(uart_t uart)
static mutex_t _tx_dma_sync[UART_NUMOF]; static mutex_t _tx_dma_sync[UART_NUMOF];
static mutex_t _tx_lock[UART_NUMOF]; static mutex_t _tx_lock[UART_NUMOF];
/**
* @brief Find out which peripheral bus the UART device is connected to
*
* @return 1: APB1
* @return 2: APB2
*/
static inline int _bus(uart_t uart)
{
return (uart_config[uart].rcc_mask < RCC_APB1ENR_USART2EN) ? 2 : 1;
}
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{ {
USART_TypeDef *dev; USART_TypeDef *dev;
@ -88,7 +77,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
uart_poweron(uart); uart_poweron(uart);
/* calculate and set baudrate */ /* calculate and set baudrate */
if (_bus(uart) == 1) { if (uart_config[uart].bus == APB1) {
divider = CLOCK_APB1 / (16 * baudrate); divider = CLOCK_APB1 / (16 * baudrate);
} }
else { else {
@ -144,22 +133,12 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
void uart_poweron(uart_t uart) void uart_poweron(uart_t uart)
{ {
if (_bus(uart) == 1) { periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask);
RCC->APB1ENR |= uart_config[uart].rcc_mask;
}
else {
RCC->APB2ENR |= uart_config[uart].rcc_mask;
}
} }
void uart_poweroff(uart_t uart) void uart_poweroff(uart_t uart)
{ {
if (_bus(uart) == 1) { periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcc_mask);
RCC->APB1ENR &= ~(uart_config[uart].rcc_mask);
}
else {
RCC->APB2ENR &= ~(uart_config[uart].rcc_mask);
}
} }
static inline void irq_handler(int uart, USART_TypeDef *dev) static inline void irq_handler(int uart, USART_TypeDef *dev)