bsp/stm32f4: API changes

This commit is contained in:
Sebastian Huber
2012-04-15 21:15:22 +02:00
parent bce41f49f0
commit 7be19f849c
9 changed files with 174 additions and 83 deletions

View File

@@ -79,6 +79,7 @@ libbsp_a_SOURCES += startup/bspstarthook.c
libbsp_a_SOURCES += startup/bspreset.c libbsp_a_SOURCES += startup/bspreset.c
libbsp_a_SOURCES += startup/io.c libbsp_a_SOURCES += startup/io.c
libbsp_a_SOURCES += startup/rcc.c libbsp_a_SOURCES += startup/rcc.c
libbsp_a_SOURCES += startup/start-config-io.c
# IRQ # IRQ
libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c

View File

@@ -35,13 +35,13 @@ RTEMS_BSPOPTS_HELP([STM32F4_PCLK2],[PCLK2 frequency in Hz])
RTEMS_BSPOPTS_SET([STM32F4_USART_BAUD],[*],[115200]) RTEMS_BSPOPTS_SET([STM32F4_USART_BAUD],[*],[115200])
RTEMS_BSPOPTS_HELP([STM32F4_USART_BAUD],[baud for USARTs]) RTEMS_BSPOPTS_HELP([STM32F4_USART_BAUD],[baud for USARTs])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_1],[*],[1]) RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_1],[*],[])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_1],[enable USART 1]) RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_1],[enable USART 1])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_2],[*],[]) RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_2],[*],[])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_2],[enable USART 2]) RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_2],[enable USART 2])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_3],[*],[]) RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_3],[*],[1])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_3],[enable USART 3]) RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_3],[enable USART 3])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_UART_4],[*],[]) RTEMS_BSPOPTS_SET([STM32F4_ENABLE_UART_4],[*],[])

View File

@@ -118,48 +118,6 @@ static uint32_t usart_get_bbr(
| STM32F4_USART_BBR_DIV_FRACTION(div_fraction); | STM32F4_USART_BBR_DIV_FRACTION(div_fraction);
} }
#define USART_CFG(port, idx, altfunc) \
{ \
.pin = STM32F4_GPIO_PIN(port, idx), \
.mode = STM32F4_GPIO_MODE_AF, \
.otype = STM32F4_GPIO_OTYPE_PUSH_PULL, \
.ospeed = STM32F4_GPIO_OSPEED_2_MHZ, \
.pupd = STM32F4_GPIO_PULL_UP, \
.af = altfunc \
}
static const stm32f4_gpio_config usart_gpio_config [] [2] = {
{
USART_CFG(0, 9, STM32F4_GPIO_AF_USART1),
USART_CFG(0, 10, STM32F4_GPIO_AF_USART1)
}, {
USART_CFG(0, 2, STM32F4_GPIO_AF_USART2),
USART_CFG(0, 3, STM32F4_GPIO_AF_USART2)
}, {
USART_CFG(3, 8, STM32F4_GPIO_AF_USART3),
USART_CFG(3, 9, STM32F4_GPIO_AF_USART3)
}, {
USART_CFG(0, 1, STM32F4_GPIO_AF_UART4),
USART_CFG(0, 2, STM32F4_GPIO_AF_UART4)
}, {
USART_CFG(2, 11, STM32F4_GPIO_AF_UART5),
USART_CFG(2, 12, STM32F4_GPIO_AF_UART5)
}, {
USART_CFG(2, 6, STM32F4_GPIO_AF_USART6),
USART_CFG(2, 7, STM32F4_GPIO_AF_USART6)
}
};
static void usart_set_gpio_config(const console_tbl *ct)
{
const stm32f4_gpio_config *config = usart_gpio_config [ct->ulCtrlPort2];
stm32f4_rcc_set_gpio_clock(config [0].pin, true);
stm32f4_gpio_set_config(&config [0]);
stm32f4_rcc_set_gpio_clock(config [1].pin, true);
stm32f4_gpio_set_config(&config [1]);
}
static void usart_initialize(int minor) static void usart_initialize(int minor)
{ {
const console_tbl *ct = Console_Port_Tbl [minor]; const console_tbl *ct = Console_Port_Tbl [minor];
@@ -169,7 +127,6 @@ static void usart_initialize(int minor)
stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct); stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct);
stm32f4_rcc_set_clock(rcc_index, true); stm32f4_rcc_set_clock(rcc_index, true);
usart_set_gpio_config(ct);
usart->cr1 = 0; usart->cr1 = 0;
usart->cr2 = 0; usart->cr2 = 0;

View File

@@ -92,21 +92,80 @@ typedef enum {
#define STM32F4_GPIO_INDEX_OF_PIN(pin) ((pin) & 0xf) #define STM32F4_GPIO_INDEX_OF_PIN(pin) ((pin) & 0xf)
typedef struct { typedef union {
uint32_t pin : 8; struct {
uint32_t pin_first : 8;
uint32_t pin_last : 8;
uint32_t mode : 2; uint32_t mode : 2;
uint32_t otype : 1; uint32_t otype : 1;
uint32_t ospeed : 2; uint32_t ospeed : 2;
uint32_t pupd : 2; uint32_t pupd : 2;
uint32_t output : 1;
uint32_t af : 4; uint32_t af : 4;
uint32_t reserved : 4;
} fields;
uint32_t value;
} stm32f4_gpio_config; } stm32f4_gpio_config;
extern const stm32f4_gpio_config stm32f4_start_config_gpio [];
void stm32f4_gpio_set_clock(int pin, bool set);
void stm32f4_gpio_set_config(const stm32f4_gpio_config *config); void stm32f4_gpio_set_config(const stm32f4_gpio_config *config);
#define STM32F4_GPIO_CONFIG_TERMINAL \
{ { 0xff, 0xff, 0x3, 0x1, 0x3, 0x3, 0x1, 0xf, 0xf } }
/**
* @brief Sets the GPIO configuration of an array terminated by
* STM32F4_GPIO_CONFIG_TERMINAL.
*/
void stm32f4_gpio_set_config_array(const stm32f4_gpio_config *configs);
void stm32f4_gpio_set_output(int pin, bool set); void stm32f4_gpio_set_output(int pin, bool set);
bool stm32f4_gpio_get_input(int pin); bool stm32f4_gpio_get_input(int pin);
#define STM32F4_PIN_USART(port, idx, altfunc) \
{ \
{ \
.pin_first = STM32F4_GPIO_PIN(port, idx), \
.pin_last = STM32F4_GPIO_PIN(port, idx), \
.mode = STM32F4_GPIO_MODE_AF, \
.otype = STM32F4_GPIO_OTYPE_PUSH_PULL, \
.ospeed = STM32F4_GPIO_OSPEED_2_MHZ, \
.pupd = STM32F4_GPIO_PULL_UP, \
.af = altfunc \
} \
}
#define STM32F4_PIN_USART1_TX_PA9 STM32F4_PIN_USART(0, 9, STM32F4_GPIO_AF_USART1)
#define STM32F4_PIN_USART1_TX_PB6 STM32F4_PIN_USART(1, 6, STM32F4_GPIO_AF_USART1)
#define STM32F4_PIN_USART1_RX_PA10 STM32F4_PIN_USART(0, 10, STM32F4_GPIO_AF_USART1)
#define STM32F4_PIN_USART1_RX_PB7 STM32F4_PIN_USART(1, 7, STM32F4_GPIO_AF_USART1)
#define STM32F4_PIN_USART2_TX_PA2 STM32F4_PIN_USART(0, 2, STM32F4_GPIO_AF_USART2)
#define STM32F4_PIN_USART2_TX_PD5 STM32F4_PIN_USART(3, 5, STM32F4_GPIO_AF_USART2)
#define STM32F4_PIN_USART2_RX_PA3 STM32F4_PIN_USART(0, 3, STM32F4_GPIO_AF_USART2)
#define STM32F4_PIN_USART2_RX_PD6 STM32F4_PIN_USART(3, 6, STM32F4_GPIO_AF_USART2)
#define STM32F4_PIN_USART3_TX_PC10 STM32F4_PIN_USART(2, 10, STM32F4_GPIO_AF_USART3)
#define STM32F4_PIN_USART3_TX_PD8 STM32F4_PIN_USART(3, 8, STM32F4_GPIO_AF_USART3)
#define STM32F4_PIN_USART3_RX_PC11 STM32F4_PIN_USART(2, 11, STM32F4_GPIO_AF_USART3)
#define STM32F4_PIN_USART3_RX_PD9 STM32F4_PIN_USART(3, 9, STM32F4_GPIO_AF_USART3)
#define STM32F4_PIN_UART4_TX_PA0 STM32F4_PIN_USART(0, 0, STM32F4_GPIO_AF_UART4)
#define STM32F4_PIN_UART4_TX_PC10 STM32F4_PIN_USART(2, 10, STM32F4_GPIO_AF_UART4)
#define STM32F4_PIN_UART4_RX_PA1 STM32F4_PIN_USART(0, 1, STM32F4_GPIO_AF_UART4)
#define STM32F4_PIN_UART4_RX_PC11 STM32F4_PIN_USART(2, 11, STM32F4_GPIO_AF_UART4)
#define STM32F4_PIN_UART5_TX_PC12 STM32F4_PIN_USART(2, 12, STM32F4_GPIO_AF_UART5)
#define STM32F4_PIN_UART5_RX_PD2 STM32F4_PIN_USART(3, 2, STM32F4_GPIO_AF_UART5)
#define STM32F4_PIN_USART6_TX_PC6 STM32F4_PIN_USART(2, 6, STM32F4_GPIO_AF_USART6)
#define STM32F4_PIN_USART6_RX_PC7 STM32F4_PIN_USART(2, 7, STM32F4_GPIO_AF_USART6)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -88,12 +88,12 @@ typedef enum {
STM32F4_RCC_TIM1 = STM32F4_RCC_INDEX(5, 0), STM32F4_RCC_TIM1 = STM32F4_RCC_INDEX(5, 0),
} stm32f4_rcc_index; } stm32f4_rcc_index;
void stm32f4_rcc_reset(stm32f4_rcc_index index, bool set); void stm32f4_rcc_reset(stm32f4_rcc_index index);
void stm32f4_rcc_set_reset(stm32f4_rcc_index index, bool set);
void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set); void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set);
void stm32f4_rcc_set_gpio_clock(int pin, bool set);
void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set); void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -13,13 +13,15 @@
*/ */
#include <bsp.h> #include <bsp.h>
#include <bsp/io.h>
#include <bsp/irq.h>
#include <bsp/bootcard.h> #include <bsp/bootcard.h>
#include <bsp/irq-generic.h> #include <bsp/irq-generic.h>
#include <bsp/irq.h>
#include <bsp/linker-symbols.h>
void bsp_start(void) void bsp_start(void)
{ {
stm32f4_gpio_set_config_array(&stm32f4_start_config_gpio [0]);
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) { if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
_CPU_Fatal_halt(0xe); _CPU_Fatal_halt(0xe);
} }

View File

@@ -13,9 +13,20 @@
*/ */
#include <bsp/io.h> #include <bsp/io.h>
#include <bsp/rcc.h>
#include <rtems.h> #include <rtems.h>
RTEMS_STATIC_ASSERT(sizeof(stm32f4_gpio_config) == 4, size_of_config);
void stm32f4_gpio_set_clock(int pin, bool set)
{
int port = STM32F4_GPIO_PORT_OF_PIN(pin);
stm32f4_rcc_index index = STM32F4_RCC_GPIOA + port;
stm32f4_rcc_set_clock(index, set);
}
static void clear_and_set( static void clear_and_set(
volatile uint32_t *reg, volatile uint32_t *reg,
unsigned index, unsigned index,
@@ -23,8 +34,7 @@ static void clear_and_set(
uint32_t set uint32_t set
) )
{ {
uint32_t one = 1; uint32_t mask = (1U << width) - 1U;
uint32_t mask = (one << width) - one;
unsigned shift = width * index; unsigned shift = width * index;
uint32_t val = *reg; uint32_t val = *reg;
@@ -34,34 +44,56 @@ static void clear_and_set(
*reg = val; *reg = val;
} }
void stm32f4_gpio_set_config(const stm32f4_gpio_config *config) static void set_config(unsigned pin, const stm32f4_gpio_config *config)
{ {
unsigned pin = config->pin;
unsigned port = STM32F4_GPIO_PORT_OF_PIN(pin); unsigned port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port); volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
unsigned index = STM32F4_GPIO_INDEX_OF_PIN(pin); unsigned index = STM32F4_GPIO_INDEX_OF_PIN(pin);
unsigned af_reg = index >> 8; unsigned af_reg = index >> 3;
unsigned af_index = index & 0x3; unsigned af_index = index & 0x7;
int set_or_clear_offset = config->fields.output ? 0 : 16;
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_interrupt_disable(level); rtems_interrupt_disable(level);
clear_and_set(&gpio->moder, index, 2, config->mode); gpio->bsrr = 1U << (index + set_or_clear_offset);
clear_and_set(&gpio->afr [af_reg], af_index, 4, config->af); clear_and_set(&gpio->pupdr, index, 2, config->fields.pupd);
clear_and_set(&gpio->pupdr, index, 2, config->pupd); clear_and_set(&gpio->otyper, index, 1, config->fields.otype);
clear_and_set(&gpio->otyper, index, 1, config->otype); clear_and_set(&gpio->ospeedr, index, 2, config->fields.ospeed);
clear_and_set(&gpio->ospeedr, index, 2, config->ospeed); clear_and_set(&gpio->afr [af_reg], af_index, 4, config->fields.af);
clear_and_set(&gpio->moder, index, 2, config->fields.mode);
rtems_interrupt_enable(level); rtems_interrupt_enable(level);
} }
void stm32f4_gpio_set_config(const stm32f4_gpio_config *config)
{
int current = config->fields.pin_first;
int last = config->fields.pin_last;
while (current <= last) {
stm32f4_gpio_set_clock(current, true);
set_config(current, config);
++current;
}
}
void stm32f4_gpio_set_config_array(const stm32f4_gpio_config *configs)
{
stm32f4_gpio_config terminal = STM32F4_GPIO_CONFIG_TERMINAL;
while (configs->value != terminal.value) {
stm32f4_gpio_set_config(configs);
++configs;
}
}
void stm32f4_gpio_set_output(int pin, bool set) void stm32f4_gpio_set_output(int pin, bool set)
{ {
int port = STM32F4_GPIO_PORT_OF_PIN(pin); int port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port); volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
int index = STM32F4_GPIO_INDEX_OF_PIN(pin); int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
int offset = set ? 0 : 16; int set_or_clear_offset = set ? 0 : 16;
uint32_t one = 1;
gpio->bsrr = one << (index + offset); gpio->bsrr = 1U << (index + set_or_clear_offset);
} }
bool stm32f4_gpio_get_input(int pin) bool stm32f4_gpio_get_input(int pin)
@@ -69,7 +101,6 @@ bool stm32f4_gpio_get_input(int pin)
int port = STM32F4_GPIO_PORT_OF_PIN(pin); int port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port); volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
int index = STM32F4_GPIO_INDEX_OF_PIN(pin); int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
uint32_t one = 1;
return (gpio->idr & (one << index)) != 0; return (gpio->idr & (1U << index)) != 0;
} }

View File

@@ -13,7 +13,6 @@
*/ */
#include <bsp/rcc.h> #include <bsp/rcc.h>
#include <bsp/io.h>
#include <rtems.h> #include <rtems.h>
@@ -40,7 +39,13 @@ static void rcc_set(
rtems_interrupt_enable(level); rtems_interrupt_enable(level);
} }
void stm32f4_rcc_reset(stm32f4_rcc_index index, bool set) void stm32f4_rcc_reset(stm32f4_rcc_index index)
{
stm32f4_rcc_set_reset(index, true);
stm32f4_rcc_set_reset(index, false);
}
void stm32f4_rcc_set_reset(stm32f4_rcc_index index, bool set)
{ {
volatile stm32f4_rcc *rcc = STM32F4_RCC; volatile stm32f4_rcc *rcc = STM32F4_RCC;
@@ -54,14 +59,6 @@ void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set)
rcc_set(index, set, &rcc->ahbenr [0]); rcc_set(index, set, &rcc->ahbenr [0]);
} }
void stm32f4_rcc_set_gpio_clock(int pin, bool set)
{
int port = STM32F4_GPIO_PORT_OF_PIN(pin);
stm32f4_rcc_index index = STM32F4_RCC_GPIOA + port;
stm32f4_rcc_set_clock(index, set);
}
void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set) void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set)
{ {
volatile stm32f4_rcc *rcc = STM32F4_RCC; volatile stm32f4_rcc *rcc = STM32F4_RCC;

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2012 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <bsp/io.h>
#include <bsp.h>
const stm32f4_gpio_config stm32f4_start_config_gpio [] = {
#ifdef STM32F4_ENABLE_USART_1
STM32F4_PIN_USART1_TX_PA9,
STM32F4_PIN_USART1_RX_PA10,
#endif
#ifdef STM32F4_ENABLE_USART_2
STM32F4_PIN_USART2_TX_PA2,
STM32F4_PIN_USART2_RX_PA3,
#endif
#ifdef STM32F4_ENABLE_USART_3
STM32F4_PIN_USART3_TX_PD8,
STM32F4_PIN_USART3_RX_PD9,
#endif
#ifdef STM32F4_ENABLE_UART_4
STM32F4_PIN_UART4_TX_PA0,
STM32F4_PIN_UART4_RX_PA1,
#endif
#ifdef STM32F4_ENABLE_UART_5
STM32F4_PIN_UART5_TX_PC12,
STM32F4_PIN_UART5_RX_PD2,
#endif
#ifdef STM32F4_ENABLE_USART_6
STM32F4_PIN_USART6_TX_PC6,
STM32F4_PIN_USART6_RX_PC7,
#endif
STM32F4_GPIO_CONFIG_TERMINAL
};