From 141f8c9ff6f71989364fbd894dd8077eb1d4a4af Mon Sep 17 00:00:00 2001 From: Hauke Petersen <hauke.petersen@fu-berlin.de> Date: Sat, 20 Feb 2016 16:46:53 +0100 Subject: [PATCH] cpu/stm32f1: adapted GPIO driver --- cpu/stm32f1/include/periph_cpu.h | 27 +++++++++++++++++++++++++ cpu/stm32f1/periph/gpio.c | 34 +++++++++++++------------------- cpu/stm32f1/periph/i2c.c | 4 ++-- cpu/stm32f1/periph/spi.c | 2 +- cpu/stm32f1/periph/uart.c | 2 +- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/cpu/stm32f1/include/periph_cpu.h b/cpu/stm32f1/include/periph_cpu.h index 4cbf4d79f9..459faaff21 100644 --- a/cpu/stm32f1/include/periph_cpu.h +++ b/cpu/stm32f1/include/periph_cpu.h @@ -58,6 +58,33 @@ typedef uint32_t gpio_t; */ #define TIMER_MAXVAL (0xffff) +/** + * @brief Generate GPIO mode bitfields + * + * We use 4 bit to determine the pin functions: + * - bit 2+3: in/out + * - bit 1: PU enable + * - bit 2: OD enable + */ +#define GPIO_MODE(mode, cnf) (mode | (cnf << 2)) + +/** + * @brief Override GPIO mode options + * + * We use 4 bit to encode CNF and MODE. + * @{ + */ +#define HAVE_GPIO_MODE_T +typedef enum { + GPIO_IN = GPIO_MODE(0, 1), /**< input w/o pull R */ + GPIO_IN_PD = GPIO_MODE(0, 2), /**< input with pull-down */ + GPIO_IN_PU = GPIO_MODE(0, 2), /**< input with pull-up */ + GPIO_OUT = GPIO_MODE(3, 0), /**< push-pull output */ + GPIO_OD = GPIO_MODE(3, 1), /**< open-drain w/o pull R */ + GPIO_OD_PU = (0xff) /**< not supported by HW */ +} gpio_mode_t; +/** @} */ + /** * @brief Override values for pull register configuration * @{ diff --git a/cpu/stm32f1/periph/gpio.c b/cpu/stm32f1/periph/gpio.c index 209402e73c..ebd8020d32 100644 --- a/cpu/stm32f1/periph/gpio.c +++ b/cpu/stm32f1/periph/gpio.c @@ -68,38 +68,32 @@ static inline int _pin_num(gpio_t pin) } -int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pullup) +int gpio_init(gpio_t pin, gpio_mode_t mode) { GPIO_TypeDef *port = _port(pin); int pin_num = _pin_num(pin); + /* open-drain output with pull-up is not supported */ + if (mode == GPIO_OD_PU) { + return -1; + } /* enable the clock for the selected port */ RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN << _port_num(pin)); - /* clear configuration */ + + /* set pin mode */ port->CR[pin_num >> 3] &= ~(0xf << ((pin_num & 0x7) * 4)); - /* set new configuration */ - if (dir == GPIO_DIR_OUT) { - if (pullup != GPIO_NOPULL) { - return -1; - } - /* set to output, push-pull, 50MHz */ - port->CR[pin_num >> 3] |= (0x3 << ((pin_num & 0x7) * 4)); - /* clear pin */ - port->BRR = (1 << pin_num); - } - else { - /* configure pin to input, pull register according to the value of - * the pullup parameter */ - port->CR[pin_num >> 3] |= ((pullup & 0xc) << ((pin_num & 0x7) * 4)); - port->ODR &= ~(1 << pin_num); - port->ODR |= ((pullup & 0x1) << pin_num); + port->CR[pin_num >> 3] |= (mode << ((pin_num & 0x7) * 4)); + /* set initial state of output register */ + port->BRR = (1 << pin_num); + if (mode == GPIO_IN_PU) { + port->BSRR = (1 << pin_num); } return 0; /* all OK */ } -int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, +int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, gpio_cb_t cb, void *arg) { int pin_num = _pin_num(pin); @@ -107,7 +101,7 @@ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, /* disable interrupts on the channel we want to edit (just in case) */ EXTI->IMR &= ~(1 << pin_num); /* configure pin as input */ - gpio_init(pin, GPIO_DIR_IN, pullup); + gpio_init(pin, mode); /* set callback */ exti_ctx[pin_num].cb = cb; exti_ctx[pin_num].arg = arg; diff --git a/cpu/stm32f1/periph/i2c.c b/cpu/stm32f1/periph/i2c.c index 48702e9fe8..7c1aef7236 100644 --- a/cpu/stm32f1/periph/i2c.c +++ b/cpu/stm32f1/periph/i2c.c @@ -167,8 +167,8 @@ static void _pin_config(gpio_t scl, gpio_t sda) { /* toggle pins to reset analog filter -> see datasheet */ /* set as output */ - gpio_init(scl, GPIO_DIR_OUT, GPIO_NOPULL); - gpio_init(sda, GPIO_DIR_OUT, GPIO_NOPULL); + gpio_init(scl, GPIO_OUT); + gpio_init(sda, GPIO_OUT); /* run through toggling sequence */ gpio_set(scl); gpio_set(sda); diff --git a/cpu/stm32f1/periph/spi.c b/cpu/stm32f1/periph/spi.c index 9c8c09240b..8075b9c91a 100644 --- a/cpu/stm32f1/periph/spi.c +++ b/cpu/stm32f1/periph/spi.c @@ -161,7 +161,7 @@ int spi_conf_pins(spi_t dev) /* configure pins for alternate function input (MISO) or output (MOSI, CLK) */ gpio_init_af(clk, GPIO_AF_OUT_PP); gpio_init_af(mosi, GPIO_AF_OUT_PP); - gpio_init(miso, GPIO_DIR_IN, GPIO_NOPULL); + gpio_init(miso, GPIO_IN); return 0; } diff --git a/cpu/stm32f1/periph/uart.c b/cpu/stm32f1/periph/uart.c index bfe88789b8..0e3cd765f9 100644 --- a/cpu/stm32f1/periph/uart.c +++ b/cpu/stm32f1/periph/uart.c @@ -66,7 +66,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) isr_ctx[uart].arg = arg; /* configure RX and TX pin */ - gpio_init(uart_config[uart].rx_pin, GPIO_DIR_IN, GPIO_NOPULL); + gpio_init(uart_config[uart].rx_pin, GPIO_IN); gpio_init_af(uart_config[uart].tx_pin, GPIO_AF_OUT_PP); /* enable the clock */ -- GitLab