From bcb9aebadd0b5ded82b30be4df3b965a53b84fd6 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Fri, 31 Jul 2015 19:55:48 +0200 Subject: [PATCH] cpu/stm32f1: modernized the GPIO driver --- cpu/stm32f1/include/periph_cpu.h | 77 ++- cpu/stm32f1/include/stm32f10x.h | 3 +- cpu/stm32f1/periph/gpio.c | 1068 ++++-------------------------- cpu/stm32f1/periph/i2c.c | 16 +- cpu/stm32f1/periph/spi.c | 8 +- cpu/stm32f1/periph/uart.c | 16 +- cpu/stm32f1/vectors.c | 22 +- 7 files changed, 229 insertions(+), 981 deletions(-) diff --git a/cpu/stm32f1/include/periph_cpu.h b/cpu/stm32f1/include/periph_cpu.h index fba3e31ad..1ded7c706 100644 --- a/cpu/stm32f1/include/periph_cpu.h +++ b/cpu/stm32f1/include/periph_cpu.h @@ -19,13 +19,88 @@ #ifndef PERIPH_CPU_H_ #define PERIPH_CPU_H_ +#include "cpu.h" #include "periph/dev_enums.h" #ifdef __cplusplus extern "C" { #endif -/* nothing defined here so far... */ +/** + * @brief Overwrite the default gpio_t type definition + * @{ + */ +#define HAVE_GPIO_T +typedef uint32_t gpio_t; +/** @} */ + +/** + * @brief Definition of a fitting UNDEF value + */ +#define GPIO_UNDEF (0xffffffff) + +/** + * @brief Define a CPU specific GPIO pin generator macro + */ +#define GPIO(x, y) ((GPIOA_BASE + (x << 10)) | y) + +/** + * @brief Override values for pull register configuration + * @{ + */ +#define HAVE_GPIO_PP_T +typedef enum { + GPIO_NOPULL = 4, /**< do not use internal pull resistors */ + GPIO_PULLUP = 9, /**< enable internal pull-up resistor */ + GPIO_PULLDOWN = 8 /**< enable internal pull-down resistor */ +} gpio_pp_t; +/** @} */ + +/** + * @brief Override flank configuration values + * @{ + */ +#define HAVE_GPIO_FLANK_T +typedef enum { + GPIO_RISING = 1, /**< emit interrupt on rising flank */ + GPIO_FALLING = 2, /**< emit interrupt on falling flank */ + GPIO_BOTH = 3 /**< emit interrupt on both flanks */ +} gpio_flank_t; +/** @} */ + +/** + * @brief Available ports on the STM32F1 family + */ +enum { + PORT_A = 0, /**< port A */ + PORT_B = 1, /**< port B */ + PORT_C = 2, /**< port C */ + PORT_D = 3, /**< port D */ + PORT_E = 4, /**< port E */ + PORT_F = 5, /**< port F */ + PORT_G = 6, /**< port G */ +}; + +/** + * @brief Define alternate function modes + * + * On this CPU, only the output pins have alternate function modes. The input + * pins have to be configured using the default gpio_init() function. + */ +typedef enum { + GPIO_AF_OUT_PP = 0xb, /**< alternate function output - push-pull */ + GPIO_AF_OUT_OD = 0xf, /**< alternate function output - open-drain */ +} gpio_af_out_t; + +/** + * @brief Configure the alternate function for the given pin + * + * @note This is meant for internal use in STM32F1 peripheral drivers only + * + * @param[in] pin pin to configure + * @param[in] af alternate function to use + */ +void gpio_init_af(gpio_t pin, gpio_af_out_t af); #ifdef __cplusplus } diff --git a/cpu/stm32f1/include/stm32f10x.h b/cpu/stm32f1/include/stm32f10x.h index 38e46ff48..0c7838efc 100644 --- a/cpu/stm32f1/include/stm32f10x.h +++ b/cpu/stm32f1/include/stm32f10x.h @@ -1009,8 +1009,7 @@ typedef struct typedef struct { - __IO uint32_t CRL; - __IO uint32_t CRH; + __IO uint32_t CR[2]; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; diff --git a/cpu/stm32f1/periph/gpio.c b/cpu/stm32f1/periph/gpio.c index b16c224ad..58e8c5704 100644 --- a/cpu/stm32f1/periph/gpio.c +++ b/cpu/stm32f1/periph/gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Freie Universität Berlin + * Copyright (C) 2014-2015 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 @@ -30,1015 +30,195 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/** + * @brief Number of available external interrupt lines + */ +#define GPIO_ISR_CHAN_NUMOF (16U) + typedef struct { gpio_cb_t cb; /**< callback called from GPIO interrupt */ void *arg; /**< argument passed to the callback */ -} gpio_state_t; +} exti_ctx_t; -static gpio_state_t config[GPIO_NUMOF]; +/** + * @brief Allocate memory for one callback and argument per EXTI channel + */ +static exti_ctx_t exti_ctx[GPIO_ISR_CHAN_NUMOF]; -int gpio_init(gpio_t dev, gpio_dir_t dir, gpio_pp_t pullup) +/** + * @brief Extract the pin's port base address from the given pin identifier + */ +static inline GPIO_TypeDef *_port(gpio_t pin) { - GPIO_TypeDef *port; - uint32_t pin; + return (GPIO_TypeDef *)(pin & ~(0x0f)); +} - switch (dev) { -#if GPIO_0_EN - case GPIO_0: - GPIO_0_CLKEN(); - port = GPIO_0_PORT; - pin = GPIO_0_PIN; - break; -#endif -#if GPIO_1_EN - case GPIO_1: - GPIO_1_CLKEN(); - port = GPIO_1_PORT; - pin = GPIO_1_PIN; - break; -#endif -#if GPIO_2_EN - case GPIO_2: - GPIO_2_CLKEN(); - port = GPIO_2_PORT; - pin = GPIO_2_PIN; - break; -#endif -#if GPIO_3_EN - case GPIO_3: - GPIO_3_CLKEN(); - port = GPIO_3_PORT; - pin = GPIO_3_PIN; - break; -#endif -#if GPIO_4_EN - case GPIO_4: - GPIO_4_CLKEN(); - port = GPIO_4_PORT; - pin = GPIO_4_PIN; - break; -#endif -#if GPIO_5_EN - case GPIO_5: - GPIO_5_CLKEN(); - port = GPIO_5_PORT; - pin = GPIO_5_PIN; - break; -#endif -#if GPIO_6_EN - case GPIO_6: - GPIO_6_CLKEN(); - port = GPIO_6_PORT; - pin = GPIO_6_PIN; - break; -#endif -#if GPIO_7_EN - case GPIO_7: - GPIO_7_CLKEN(); - port = GPIO_7_PORT; - pin = GPIO_7_PIN; - break; -#endif -#if GPIO_8_EN - case GPIO_8: - GPIO_8_CLKEN(); - port = GPIO_8_PORT; - pin = GPIO_8_PIN; - break; -#endif -#if GPIO_9_EN - case GPIO_9: - GPIO_9_CLKEN(); - port = GPIO_9_PORT; - pin = GPIO_9_PIN; - break; -#endif -#if GPIO_10_EN - case GPIO_10: - GPIO_10_CLKEN(); - port = GPIO_10_PORT; - pin = GPIO_10_PIN; - break; -#endif -#if GPIO_11_EN - case GPIO_11: - GPIO_11_CLKEN(); - port = GPIO_11_PORT; - pin = GPIO_11_PIN; - break; -#endif -#if GPIO_12_EN - case GPIO_12: - GPIO_12_CLKEN(); - port = GPIO_12_PORT; - pin = GPIO_12_PIN; - break; -#endif -#if GPIO_13_EN - case GPIO_13: - GPIO_13_CLKEN(); - port = GPIO_13_PORT; - pin = GPIO_13_PIN; - break; -#endif -#if GPIO_14_EN - case GPIO_14: - GPIO_14_CLKEN(); - port = GPIO_14_PORT; - pin = GPIO_14_PIN; - break; -#endif -#if GPIO_15_EN - case GPIO_15: - GPIO_15_CLKEN(); - port = GPIO_15_PORT; - pin = GPIO_15_PIN; - break; -#endif +/** + * @brief Extract the port number from the given pin identifier + * + * Isolating bits 10 to 13 of the port base addresses leads to unique port + * numbers. + */ +static inline int _port_num(gpio_t pin) +{ + return (((pin >> 10) & 0x0f) - 2); +} - default: - return -1; - } +/** + * @brief Get the pin number from the pin identifier, encoded in the LSB 4 bit + */ +static inline int _pin_num(gpio_t pin) +{ + return (pin & 0x0f); +} + + +int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pullup) +{ + GPIO_TypeDef *port = _port(pin); + int pin_num = _pin_num(pin); + + /* enable the clock for the selected port */ + RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN << _port_num(pin)); + /* clear configuration */ + port->CR[pin_num >> 3] &= ~(0xf << ((pin_num & 0x7) * 4)); + /* set new configuration */ if (dir == GPIO_DIR_OUT) { - if (pin < 8) { - port->CRL &= ~(0xf << (4 * pin)); - port->CRL |= (0x3 << (4* pin)); /* Output mode, 50 MHz */ - /* general purpose push-pull set implicitly */ - } - else { - port->CRH &= ~(0xf << (4 * (pin-8))); - port->CRH |= (0x3 << (4* (pin-8))); /* Output mode, 50 MHz */ - /* general purpose push-pull set implicitly */ + 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 { - if (pin < 8) { - port->CRL &= ~(0xf << (4 * pin)); - port->CRL |= (0x4 << (4 * pin)); - } - else { - port->CRL &= ~(0xf << (4 * pin)); - port->CRH |= (0x4 << (4 * (pin-8))); - } + /* 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); } return 0; /* all OK */ } -int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb, void *arg) +int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, + gpio_cb_t cb, void *arg) { - int res; - uint8_t exti_line; - uint8_t gpio_irq; + int pin_num = _pin_num(pin); + /* disable interrupts on the channel we want to edit (just in case) */ + EXTI->IMR &= ~(1 << pin_num); /* configure pin as input */ - res = gpio_init(dev, GPIO_DIR_IN, pullup); - if (res < 0) { - return res; - } - - /* set interrupt priority (its the same for all EXTI interrupts) */ - NVIC_SetPriority(EXTI0_IRQn, GPIO_IRQ_PRIO); - NVIC_SetPriority(EXTI1_IRQn, GPIO_IRQ_PRIO); - NVIC_SetPriority(EXTI2_IRQn, GPIO_IRQ_PRIO); - NVIC_SetPriority(EXTI4_IRQn, GPIO_IRQ_PRIO); - + gpio_init(pin, GPIO_DIR_IN, pullup); + /* set callback */ + exti_ctx[pin_num].cb = cb; + exti_ctx[pin_num].arg = arg; + /* enable alternate function clock for the GPIO module */ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; - - /* read pin number, set EXTI channel and enable global interrupt for EXTI channel */ - switch (dev) { -#if GPIO_0_EN - case GPIO_0: - exti_line = GPIO_0_PIN; - gpio_irq = GPIO_0; - GPIO_0_EXTI_CFG(); - NVIC_SetPriority(GPIO_0_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_0_IRQ); - break; -#endif -#if GPIO_1_EN - case GPIO_1: - exti_line = GPIO_1_PIN; - gpio_irq = GPIO_1; - GPIO_1_EXTI_CFG(); - NVIC_SetPriority(GPIO_1_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_1_IRQ); - break; -#endif -#if GPIO_2_EN - case GPIO_2: - exti_line = GPIO_2_PIN; - gpio_irq = GPIO_2; - GPIO_2_EXTI_CFG(); - NVIC_SetPriority(GPIO_2_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_2_IRQ); - break; -#endif -#if GPIO_3_EN - case GPIO_3: - exti_line = GPIO_3_PIN; - gpio_irq = GPIO_3; - GPIO_3_EXTI_CFG(); - NVIC_SetPriority(GPIO_3_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_3_IRQ); - break; -#endif -#if GPIO_4_EN - case GPIO_4: - exti_line = GPIO_4_PIN; - gpio_irq = GPIO_4; - GPIO_4_EXTI_CFG(); - NVIC_SetPriority(GPIO_4_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_4_IRQ); - break; -#endif -#if GPIO_5_EN - case GPIO_5: - exti_line = GPIO_5_PIN; - gpio_irq = GPIO_5; - GPIO_5_EXTI_CFG(); - NVIC_SetPriority(GPIO_5_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_5_IRQ); - break; -#endif -#if GPIO_6_EN - case GPIO_6: - exti_line = GPIO_6_PIN; - gpio_irq = GPIO_6; - GPIO_6_EXTI_CFG(); - NVIC_SetPriority(GPIO_6_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_6_IRQ); - break; -#endif -#if GPIO_7_EN - case GPIO_7: - exti_line = GPIO_7_PIN; - gpio_irq = GPIO_7; - GPIO_7_EXTI_CFG(); - NVIC_SetPriority(GPIO_7_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_7_IRQ); - break; -#endif -#if GPIO_8_EN - case GPIO_8: - exti_line = GPIO_8_PIN; - gpio_irq = GPIO_8; - GPIO_8_EXTI_CFG(); - NVIC_SetPriority(GPIO_8_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_8_IRQ); - break; -#endif -#if GPIO_9_EN - case GPIO_9: - exti_line = GPIO_9_PIN; - gpio_irq = GPIO_9; - GPIO_9_EXTI_CFG(); - NVIC_SetPriority(GPIO_9_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_9_IRQ); - break; -#endif -#if GPIO_10_EN - case GPIO_10: - exti_line = GPIO_10_PIN; - gpio_irq = GPIO_10; - GPIO_10_EXTI_CFG(); - NVIC_SetPriority(GPIO_10_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_10_IRQ); - break; -#endif -#if GPIO_11_EN - case GPIO_11: - exti_line = GPIO_11_PIN; - gpio_irq = GPIO_11; - GPIO_11_EXTI_CFG(); - NVIC_SetPriority(GPIO_11_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_11_IRQ); - break; -#endif -#if GPIO_12_EN - case GPIO_12: - exti_line = GPIO_12_PIN; - gpio_irq = GPIO_12; - GPIO_12_EXTI_CFG(); - NVIC_SetPriority(GPIO_12_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_12_IRQ); - break; -#endif -#if GPIO_13_EN - case GPIO_13: - exti_line = GPIO_13_PIN; - gpio_irq = GPIO_13; - GPIO_13_EXTI_CFG(); - NVIC_SetPriority(GPIO_13_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_13_IRQ); - break; -#endif -#if GPIO_14_EN - case GPIO_14: - exti_line = GPIO_14_PIN; - gpio_irq = GPIO_14; - GPIO_14_EXTI_CFG(); - NVIC_SetPriority(GPIO_14_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_14_IRQ); - break; -#endif -#if GPIO_15_EN - case GPIO_15: - exti_line = GPIO_15_PIN; - gpio_irq = GPIO_15; - GPIO_15_EXTI_CFG(); - NVIC_SetPriority(GPIO_15_IRQ, GPIO_IRQ_PRIO); - NVIC_EnableIRQ(GPIO_15_IRQ); - break; -#endif - default: - return -1; + /* configure the EXTI channel */ + AFIO->EXTICR[pin_num >> 2] &= ~(0xf << ((pin_num & 0x3) * 4)); + AFIO->EXTICR[pin_num >> 2] |= (_port_num(pin) << ((pin_num & 0x3) * 4)); + /* configure the active flank */ + EXTI->RTSR &= ~(1 << pin_num); + EXTI->RTSR |= ((flank & 0x1) << pin_num); + EXTI->FTSR &= ~(1 << pin_num); + EXTI->FTSR |= ((flank >> 1) << pin_num); + /* active global interrupt for the selected port */ + if (pin_num < 5) { + NVIC_EnableIRQ(EXTI0_IRQn + pin_num); + } + else if (pin_num < 10) { + NVIC_EnableIRQ(EXTI9_5_IRQn); } - - /* set callback */ - config[gpio_irq].cb = cb; - config[gpio_irq].arg = arg; - - /* configure the event that triggers an interrupt */ - switch (flank) { - case GPIO_RISING: - EXTI->RTSR |= (1 << exti_line); - EXTI->FTSR &= ~(1 << exti_line); - break; - case GPIO_FALLING: - EXTI->RTSR &= ~(1 << exti_line); - EXTI->FTSR |= (1 << exti_line); - break; - case GPIO_BOTH: - EXTI->RTSR |= (1 << exti_line); - EXTI->FTSR |= (1 << exti_line); - break; + else { + NVIC_EnableIRQ(EXTI15_10_IRQn); } - /* clear event mask */ - EXTI->EMR &= ~(1 << exti_line); + EXTI->EMR &= ~(1 << pin_num); /* unmask the pins interrupt channel */ - EXTI->IMR |= (1 << exti_line); - + EXTI->IMR |= (1 << pin_num); return 0; } -void gpio_irq_enable(gpio_t dev) +void gpio_init_af(gpio_t pin, gpio_af_out_t af) { - uint8_t exti_line; - - switch(dev) { -#if GPIO_0_EN - case GPIO_0: - exti_line = GPIO_0_PIN; - break; -#endif -#if GPIO_1_EN - case GPIO_1: - exti_line = GPIO_1_PIN; - break; -#endif -#if GPIO_2_EN - case GPIO_2: - exti_line = GPIO_2_PIN; - break; -#endif -#if GPIO_3_EN - case GPIO_3: - exti_line = GPIO_3_PIN; - break; -#endif -#if GPIO_4_EN - case GPIO_4: - exti_line = GPIO_4_PIN; - break; -#endif -#if GPIO_5_EN - case GPIO_5: - exti_line = GPIO_5_PIN; - break; -#endif -#if GPIO_6_EN - case GPIO_6: - exti_line = GPIO_6_PIN; - break; -#endif -#if GPIO_7_EN - case GPIO_7: - exti_line = GPIO_7_PIN; - break; -#endif -#if GPIO_8_EN - case GPIO_8: - exti_line = GPIO_8_PIN; - break; -#endif -#if GPIO_9_EN - case GPIO_9: - exti_line = GPIO_9_PIN; - break; -#endif -#if GPIO_10_EN - case GPIO_10: - exti_line = GPIO_10_PIN; - break; -#endif -#if GPIO_11_EN - case GPIO_11: - exti_line = GPIO_11_PIN; - break; -#endif -#if GPIO_12_EN - case GPIO_12: - exti_line = GPIO_12_PIN; - break; -#endif -#if GPIO_13_EN - case GPIO_13: - exti_line = GPIO_13_PIN; - break; -#endif -#if GPIO_14_EN - case GPIO_14: - exti_line = GPIO_14_PIN; - break; -#endif -#if GPIO_15_EN - case GPIO_15: - exti_line = GPIO_15_PIN; - break; -#endif - default: - return; - } - - /* unmask the pins interrupt channel */ - EXTI->IMR |= (1 << exti_line); + int pin_num = _pin_num(pin); + GPIO_TypeDef *port = _port(pin); - return; + /* enable the clock for the selected port */ + RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN << _port_num(pin)); + /* configure the pin */ + port->CR[pin_num >> 3] &= ~(0xf << ((pin_num & 0x7) * 4)); + port->CR[pin_num >> 3] |= (af << ((pin_num & 0x7) * 4)); } -void gpio_irq_disable(gpio_t dev) +void gpio_irq_enable(gpio_t pin) { - uint8_t exti_line; - - switch(dev) { -#if GPIO_0_EN - case GPIO_0: - exti_line = GPIO_0_PIN; - break; -#endif -#if GPIO_1_EN - case GPIO_1: - exti_line = GPIO_1_PIN; - break; -#endif -#if GPIO_2_EN - case GPIO_2: - exti_line = GPIO_2_PIN; - break; -#endif -#if GPIO_3_EN - case GPIO_3: - exti_line = GPIO_3_PIN; - break; -#endif -#if GPIO_4_EN - case GPIO_4: - exti_line = GPIO_4_PIN; - break; -#endif -#if GPIO_5_EN - case GPIO_5: - exti_line = GPIO_5_PIN; - break; -#endif -#if GPIO_6_EN - case GPIO_6: - exti_line = GPIO_6_PIN; - break; -#endif -#if GPIO_7_EN - case GPIO_7: - exti_line = GPIO_7_PIN; - break; -#endif -#if GPIO_8_EN - case GPIO_8: - exti_line = GPIO_8_PIN; - break; -#endif -#if GPIO_9_EN - case GPIO_9: - exti_line = GPIO_9_PIN; - break; -#endif -#if GPIO_10_EN - case GPIO_10: - exti_line = GPIO_10_PIN; - break; -#endif -#if GPIO_11_EN - case GPIO_11: - exti_line = GPIO_11_PIN; - break; -#endif -#if GPIO_12_EN - case GPIO_12: - exti_line = GPIO_12_PIN; - break; -#endif -#if GPIO_13_EN - case GPIO_13: - exti_line = GPIO_13_PIN; - break; -#endif -#if GPIO_14_EN - case GPIO_14: - exti_line = GPIO_14_PIN; - break; -#endif -#if GPIO_15_EN - case GPIO_15: - exti_line = GPIO_15_PIN; - break; -#endif - default: - return; - } - - /* unmask the pins interrupt channel */ - EXTI->IMR &= ~(1 << exti_line); - - return; + EXTI->IMR |= (1 << _pin_num(pin)); } -int gpio_read(gpio_t dev) +void gpio_irq_disable(gpio_t pin) { - GPIO_TypeDef *port; - uint32_t pin; + EXTI->IMR &= ~(1 << _pin_num(pin)); +} - switch (dev) { -#if GPIO_0_EN - case GPIO_0: - port = GPIO_0_PORT; - pin = GPIO_0_PIN; - break; -#endif -#if GPIO_1_EN - case GPIO_1: - port = GPIO_1_PORT; - pin = GPIO_1_PIN; - break; -#endif -#if GPIO_2_EN - case GPIO_2: - port = GPIO_2_PORT; - pin = GPIO_2_PIN; - break; -#endif -#if GPIO_3_EN - case GPIO_3: - port = GPIO_3_PORT; - pin = GPIO_3_PIN; - break; -#endif -#if GPIO_4_EN - case GPIO_4: - port = GPIO_4_PORT; - pin = GPIO_4_PIN; - break; -#endif -#if GPIO_5_EN - case GPIO_5: - port = GPIO_5_PORT; - pin = GPIO_5_PIN; - break; -#endif -#if GPIO_6_EN - case GPIO_6: - port = GPIO_6_PORT; - pin = GPIO_6_PIN; - break; -#endif -#if GPIO_7_EN - case GPIO_7: - port = GPIO_7_PORT; - pin = GPIO_7_PIN; - break; -#endif -#if GPIO_8_EN - case GPIO_8: - port = GPIO_8_PORT; - pin = GPIO_8_PIN; - break; -#endif -#if GPIO_9_EN - case GPIO_9: - port = GPIO_9_PORT; - pin = GPIO_9_PIN; - break; -#endif -#if GPIO_10_EN - case GPIO_10: - port = GPIO_10_PORT; - pin = GPIO_10_PIN; - break; -#endif -#if GPIO_11_EN - case GPIO_11: - port = GPIO_11_PORT; - pin = GPIO_11_PIN; - break; -#endif -#if GPIO_12_EN - case GPIO_12: - port = GPIO_12_PORT; - pin = GPIO_12_PIN; - break; -#endif -#if GPIO_13_EN - case GPIO_13: - port = GPIO_13_PORT; - pin = GPIO_13_PIN; - break; -#endif -#if GPIO_14_EN - case GPIO_14: - port = GPIO_14_PORT; - pin = GPIO_14_PIN; - break; -#endif -#if GPIO_15_EN - case GPIO_15: - port = GPIO_15_PORT; - pin = GPIO_15_PIN; - break; -#endif - default: - return -1; - } +int gpio_read(gpio_t pin) +{ + GPIO_TypeDef *port = _port(pin); + int pin_num = _pin_num(pin); - if (pin < 8) { - if (port->CRL & (0x3 << (pin * 4))) { /* if configured as output */ - return port->ODR & (1 << pin); /* read output data register */ - } else { - return port->IDR & (1 << pin); /* else read input data register */ - } + if (port->CR[pin_num >> 3] & (0x3 << (pin_num & 0x7))) { + /* pin is output */ + return (port->ODR & (1 << pin_num)); } else { - if (port->CRH & (0x3 << ((pin-8) * 4))) { /* if configured as output */ - return port->ODR & (1 << pin); /* read output data register */ - } else { - return port->IDR & (1 << pin); /* else read input data register */ - } + /* or input */ + return (port->IDR & (1 << pin_num)); } } -void gpio_set(gpio_t dev) +void gpio_set(gpio_t pin) { - switch (dev) { -#if GPIO_0_EN - case GPIO_0: - GPIO_0_PORT->BSRR = (1 << GPIO_0_PIN); - break; -#endif -#if GPIO_1_EN - case GPIO_1: - GPIO_1_PORT->BSRR = (1 << GPIO_1_PIN); - break; -#endif -#if GPIO_2_EN - case GPIO_2: - GPIO_2_PORT->BSRR = (1 << GPIO_2_PIN); - break; -#endif -#if GPIO_3_EN - case GPIO_3: - GPIO_3_PORT->BSRR = (1 << GPIO_3_PIN); - break; -#endif -#if GPIO_4_EN - case GPIO_4: - GPIO_4_PORT->BSRR = (1 << GPIO_4_PIN); - break; -#endif -#if GPIO_5_EN - case GPIO_5: - GPIO_5_PORT->BSRR = (1 << GPIO_5_PIN); - break; -#endif -#if GPIO_6_EN - case GPIO_6: - GPIO_6_PORT->BSRR = (1 << GPIO_6_PIN); - break; -#endif -#if GPIO_7_EN - case GPIO_7: - GPIO_7_PORT->BSRR = (1 << GPIO_7_PIN); - break; -#endif -#if GPIO_8_EN - case GPIO_8: - GPIO_8_PORT->BSRR = (1 << GPIO_8_PIN); - break; -#endif -#if GPIO_9_EN - case GPIO_9: - GPIO_9_PORT->BSRR = (1 << GPIO_9_PIN); - break; -#endif -#if GPIO_10_EN - case GPIO_10: - GPIO_10_PORT->BSRR = (1 << GPIO_10_PIN); - break; -#endif -#if GPIO_11_EN - case GPIO_11: - GPIO_11_PORT->BSRR = (1 << GPIO_11_PIN); - break; -#endif -#if GPIO_12_EN - case GPIO_12: - GPIO_12_PORT->BSRR = (1 << GPIO_12_PIN); - break; -#endif -#if GPIO_13_EN - case GPIO_13: - GPIO_13_PORT->BSRR = (1 << GPIO_13_PIN); - break; -#endif -#if GPIO_14_EN - case GPIO_14: - GPIO_14_PORT->BSRR = (1 << GPIO_14_PIN); - break; -#endif -#if GPIO_15_EN - case GPIO_15: - GPIO_15_PORT->BSRR = (1 << GPIO_15_PIN); - break; -#endif - } + _port(pin)->BSRR = (1 << _pin_num(pin)); } -void gpio_clear(gpio_t dev) +void gpio_clear(gpio_t pin) { - switch (dev) { -#if GPIO_0_EN - case GPIO_0: - GPIO_0_PORT->BRR = (1 << GPIO_0_PIN); - break; -#endif -#if GPIO_1_EN - case GPIO_1: - GPIO_1_PORT->BRR = (1 << GPIO_1_PIN); - break; -#endif -#if GPIO_2_EN - case GPIO_2: - GPIO_2_PORT->BRR = (1 << GPIO_2_PIN); - break; -#endif -#if GPIO_3_EN - case GPIO_3: - GPIO_3_PORT->BRR = (1 << GPIO_3_PIN); - break; -#endif -#if GPIO_4_EN - case GPIO_4: - GPIO_4_PORT->BRR = (1 << GPIO_4_PIN); - break; -#endif -#if GPIO_5_EN - case GPIO_5: - GPIO_5_PORT->BRR = (1 << GPIO_5_PIN); - break; -#endif -#if GPIO_6_EN - case GPIO_6: - GPIO_6_PORT->BRR = (1 << GPIO_6_PIN); - break; -#endif -#if GPIO_7_EN - case GPIO_7: - GPIO_7_PORT->BRR = (1 << GPIO_7_PIN); - break; -#endif -#if GPIO_8_EN - case GPIO_8: - GPIO_8_PORT->BRR = (1 << GPIO_8_PIN); - break; -#endif -#if GPIO_9_EN - case GPIO_9: - GPIO_9_PORT->BRR = (1 << GPIO_9_PIN); - break; -#endif -#if GPIO_10_EN - case GPIO_10: - GPIO_10_PORT->BRR = (1 << GPIO_10_PIN); - break; -#endif -#if GPIO_11_EN - case GPIO_11: - GPIO_11_PORT->BRR = (1 << GPIO_11_PIN); - break; -#endif -#if GPIO_12_EN - case GPIO_12: - GPIO_12_PORT->BRR = (1 << GPIO_12_PIN); - break; -#endif -#if GPIO_13_EN - case GPIO_13: - GPIO_13_PORT->BRR = (1 << GPIO_13_PIN); - break; -#endif -#if GPIO_14_EN - case GPIO_14: - GPIO_14_PORT->BRR = (1 << GPIO_14_PIN); - break; -#endif -#if GPIO_15_EN - case GPIO_15: - GPIO_15_PORT->BRR = (1 << GPIO_15_PIN); - break; -#endif - } + _port(pin)->BRR = (1 << _pin_num(pin)); } - -void gpio_toggle(gpio_t dev) +void gpio_toggle(gpio_t pin) { - if (gpio_read(dev)) { - gpio_clear(dev); + if (gpio_read(pin)) { + gpio_clear(pin); } else { - gpio_set(dev); + gpio_set(pin); } } -void gpio_write(gpio_t dev, int value) +void gpio_write(gpio_t pin, int value) { if (value) { - gpio_set(dev); + _port(pin)->BSRR = (1 << _pin_num(pin)); } else { - gpio_clear(dev); + _port(pin)->BRR = (1 << _pin_num(pin)); } } -#ifdef GPIO_IRQ_0 -void isr_exti0(void) +void isr_exti(void) { - if (EXTI->PR & EXTI_PR_PR0) { - EXTI->PR |= EXTI_PR_PR0; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_0].cb(config[GPIO_IRQ_0].arg); - } - - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#ifdef GPIO_IRQ_1 -void isr_exti1(void) -{ - if (EXTI->PR & EXTI_PR_PR1) { - EXTI->PR |= EXTI_PR_PR1; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_1].cb(config[GPIO_IRQ_1].arg); - } - - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#ifdef GPIO_IRQ_2 -void isr_exti2(void) -{ - if (EXTI->PR & EXTI_PR_PR2) { - EXTI->PR |= EXTI_PR_PR2; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_2].cb(config[GPIO_IRQ_2].arg); - } - - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#ifdef GPIO_IRQ_3 -void isr_exti3(void) -{ - if (EXTI->PR & EXTI_PR_PR3) { - EXTI->PR |= EXTI_PR_PR3; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_3].cb(config[GPIO_IRQ_3].arg); - } - - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#ifdef GPIO_IRQ_4 -void isr_exti4(void) -{ - if (EXTI->PR & EXTI_PR_PR4) { - EXTI->PR |= EXTI_PR_PR4; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_4].cb(config[GPIO_IRQ_4].arg); - } - - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#if defined(GPIO_IRQ_5) || defined(GPIO_IRQ_6) || defined(GPIO_IRQ_7) || defined(GPIO_IRQ_8) || defined(GPIO_IRQ_9) -void isr_exti9_5(void) -{ -#ifdef GPIO_IRQ_5 - if (EXTI->PR & EXTI_PR_PR5) { - EXTI->PR |= EXTI_PR_PR5; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_5].cb(config[GPIO_IRQ_5].arg); - } -#endif -#ifdef GPIO_IRQ_6 - if (EXTI->PR & EXTI_PR_PR6) { - EXTI->PR |= EXTI_PR_PR6; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_6].cb(config[GPIO_IRQ_6].arg); - } -#endif -#ifdef GPIO_IRQ_7 - if (EXTI->PR & EXTI_PR_PR7) { - EXTI->PR |= EXTI_PR_PR7; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_7].cb(config[GPIO_IRQ_7].arg); - } -#endif -#ifdef GPIO_IRQ_8 - if (EXTI->PR & EXTI_PR_PR8) { - EXTI->PR |= EXTI_PR_PR8; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_8].cb(config[GPIO_IRQ_8].arg); - } -#endif -#ifdef GPIO_IRQ_9 - if (EXTI->PR & EXTI_PR_PR9) { - EXTI->PR |= EXTI_PR_PR9; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_9].cb(config[GPIO_IRQ_9].arg); - } -#endif - if (sched_context_switch_request) { - thread_yield(); - } -} -#endif - -#if defined(GPIO_IRQ_10) || defined(GPIO_IRQ_11) || defined(GPIO_IRQ_12) || defined(GPIO_IRQ_13) || defined(GPIO_IRQ_14) || defined(GPIO_IRQ_15) -void isr_exti15_10(void) -{ -#ifdef GPIO_IRQ_10 - if (EXTI->PR & EXTI_PR_PR10) { - EXTI->PR |= EXTI_PR_PR10; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_10].cb(config[GPIO_IRQ_10].arg); - } -#endif -#ifdef GPIO_IRQ_11 - if (EXTI->PR & EXTI_PR_PR11) { - EXTI->PR |= EXTI_PR_PR11; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_11].cb(config[GPIO_IRQ_11].arg); - } -#endif -#ifdef GPIO_IRQ_12 - if (EXTI->PR & EXTI_PR_PR12) { - EXTI->PR |= EXTI_PR_PR12; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_12].cb(config[GPIO_IRQ_12].arg); - } -#endif -#ifdef GPIO_IRQ_13 - if (EXTI->PR & EXTI_PR_PR13) { - EXTI->PR |= EXTI_PR_PR13; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_13].cb(config[GPIO_IRQ_13].arg); - } -#endif -#ifdef GPIO_IRQ_14 - if (EXTI->PR & EXTI_PR_PR14) { - EXTI->PR |= EXTI_PR_PR14; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_14].cb(config[GPIO_IRQ_14].arg); - } -#endif -#ifdef GPIO_IRQ_15 - if (EXTI->PR & EXTI_PR_PR15) { - EXTI->PR |= EXTI_PR_PR15; /* clear status bit by writing a 1 to it */ - config[GPIO_IRQ_15].cb(config[GPIO_IRQ_15].arg); + for (int i = 0; i < GPIO_ISR_CHAN_NUMOF; i++) { + if (EXTI->PR & (1 << i)) { + EXTI->PR = (1 << i); /* clear by writing a 1 */ + exti_ctx[i].cb(exti_ctx[i].arg); + } } -#endif if (sched_context_switch_request) { thread_yield(); } } -#endif diff --git a/cpu/stm32f1/periph/i2c.c b/cpu/stm32f1/periph/i2c.c index 808c5ff25..fdd730f96 100644 --- a/cpu/stm32f1/periph/i2c.c +++ b/cpu/stm32f1/periph/i2c.c @@ -147,16 +147,16 @@ static void _pin_config(GPIO_TypeDef *port_scl, GPIO_TypeDef *port_sda, int pin_ { /* configure pins, alternate output, open-drain, output mode with 50MHz */ if (pin_scl < 8) { - port_scl->CRL |= (0xf << (pin_scl * 4)); + port_scl->CR[0] |= (0xf << (pin_scl * 4)); } else { - port_scl->CRH |= (0xf << ((pin_scl - 8) * 4)); + port_scl->CR[1] |= (0xf << ((pin_scl - 8) * 4)); } if (pin_sda < 8) { - port_sda->CRL |= (0xf << (pin_sda * 4)); + port_sda->CR[0] |= (0xf << (pin_sda * 4)); } else { - port_sda->CRH |= (0xf << ((pin_sda - 8) * 4)); + port_sda->CR[1] |= (0xf << ((pin_sda - 8) * 4)); } } @@ -164,16 +164,16 @@ static void _toggle_pins(GPIO_TypeDef *port_scl, GPIO_TypeDef *port_sda, int pin { /* configure pins, output, open-drain, output mode with 50MHz */ if (pin_scl < 8) { - port_scl->CRL |= (0x7 << (pin_scl * 4)); + port_scl->CR[0] |= (0x7 << (pin_scl * 4)); } else { - port_scl->CRH |= (0x7 << ((pin_scl - 8) * 4)); + port_scl->CR[1] |= (0x7 << ((pin_scl - 8) * 4)); } if (pin_sda < 8) { - port_sda->CRL |= (0x7 << (pin_sda * 4)); + port_sda->CR[0] |= (0x7 << (pin_sda * 4)); } else { - port_sda->CRH |= (0x7 << ((pin_sda - 8) * 4)); + port_sda->CR[1] |= (0x7 << ((pin_sda - 8) * 4)); } /* set both to high */ port_scl->ODR |= (1 << pin_scl); diff --git a/cpu/stm32f1/periph/spi.c b/cpu/stm32f1/periph/spi.c index cd1f32a22..5772eee56 100644 --- a/cpu/stm32f1/periph/spi.c +++ b/cpu/stm32f1/periph/spi.c @@ -131,12 +131,12 @@ int spi_conf_pins(spi_t dev) for (int i = 0; i < 3; i++) { int crbitval = (i < 2) ? 0xb : 0x4; if (pin[i] < 8) { - port[i]->CRL &= ~(0xf << (pin[i] * 4)); - port[i]->CRL |= (crbitval << (pin[i] * 4)); + port[i]->CR[0] &= ~(0xf << (pin[i] * 4)); + port[i]->CR[0] |= (crbitval << (pin[i] * 4)); } else { - port[i]->CRH &= ~(0xf << ((pin[i] - 8) * 4)); - port[i]->CRH |= (crbitval << ((pin[i] - 8) * 4)); + port[i]->CR[1] &= ~(0xf << ((pin[i] - 8) * 4)); + port[i]->CR[1] |= (crbitval << ((pin[i] - 8) * 4)); } } diff --git a/cpu/stm32f1/periph/uart.c b/cpu/stm32f1/periph/uart.c index 1e6fc69b5..cebe493d4 100644 --- a/cpu/stm32f1/periph/uart.c +++ b/cpu/stm32f1/periph/uart.c @@ -136,21 +136,21 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate) } /* Configure USART Tx as alternate function push-pull and 50MHz*/ if (tx_pin < 8) { - port->CRL &= ~(0xf << (tx_pin * 4)); - port->CRL |= (0xB << (tx_pin * 4)); + port->CR[0] &= ~(0xf << (tx_pin * 4)); + port->CR[0] |= (0xB << (tx_pin * 4)); } else { - port->CRH &= ~(0xf << ((tx_pin-8) * 4)); - port->CRH |= (0xB << ((tx_pin-8) * 4)); + port->CR[1] &= ~(0xf << ((tx_pin-8) * 4)); + port->CR[1] |= (0xB << ((tx_pin-8) * 4)); } /* Configure USART Rx as floating input */ if (rx_pin < 8) { - port->CRL &= ~(0xf << (rx_pin * 4)); - port->CRL |= (0x4 << (rx_pin * 4)); + port->CR[0] &= ~(0xf << (rx_pin * 4)); + port->CR[0] |= (0x4 << (rx_pin * 4)); } else { - port->CRH &= ~(0xf << ((rx_pin-8) * 4)); - port->CRH |= (0x4 << ((rx_pin-8) * 4)); + port->CR[1] &= ~(0xf << ((rx_pin-8) * 4)); + port->CR[1] |= (0x4 << ((rx_pin-8) * 4)); } /* configure UART to mode 8N1 with given baudrate */ diff --git a/cpu/stm32f1/vectors.c b/cpu/stm32f1/vectors.c index e2fe96449..38b4a73d9 100644 --- a/cpu/stm32f1/vectors.c +++ b/cpu/stm32f1/vectors.c @@ -42,11 +42,7 @@ WEAK_DEFAULT void isr_tamper(void); WEAK_DEFAULT void isr_rtc(void); WEAK_DEFAULT void isr_flash(void); WEAK_DEFAULT void isr_rcc(void); -WEAK_DEFAULT void isr_exti0(void); -WEAK_DEFAULT void isr_exti1(void); -WEAK_DEFAULT void isr_exti2(void); -WEAK_DEFAULT void isr_exti3(void); -WEAK_DEFAULT void isr_exti4(void); +WEAK_DEFAULT void isr_exti(void); WEAK_DEFAULT void isr_dma1_ch1(void); WEAK_DEFAULT void isr_dma1_ch2(void); WEAK_DEFAULT void isr_dma1_ch3(void); @@ -59,7 +55,6 @@ WEAK_DEFAULT void isr_usb_hp_can1_tx(void); WEAK_DEFAULT void isr_usb_lp_can1_rx0(void); WEAK_DEFAULT void isr_can1_rx1(void); WEAK_DEFAULT void isr_can1_sce(void); -WEAK_DEFAULT void isr_exti9_5(void); WEAK_DEFAULT void isr_tim1_brk(void); WEAK_DEFAULT void isr_tim1_up(void); WEAK_DEFAULT void isr_tim1_trg_com(void); @@ -76,7 +71,6 @@ WEAK_DEFAULT void isr_spi2(void); WEAK_DEFAULT void isr_usart1(void); WEAK_DEFAULT void isr_usart2(void); WEAK_DEFAULT void isr_usart3(void); -WEAK_DEFAULT void isr_exti15_10(void); WEAK_DEFAULT void isr_rtc_alarm(void); WEAK_DEFAULT void isr_usb_wakeup(void); WEAK_DEFAULT void isr_tim8_brk(void); @@ -126,11 +120,11 @@ ISR_VECTORS const void *interrupt_vector[] = { (void*) isr_rtc, (void*) isr_flash, (void*) isr_rcc, - (void*) isr_exti0, - (void*) isr_exti1, - (void*) isr_exti2, - (void*) isr_exti3, - (void*) isr_exti4, + (void*) isr_exti, + (void*) isr_exti, + (void*) isr_exti, + (void*) isr_exti, + (void*) isr_exti, (void*) isr_dma1_ch1, (void*) isr_dma1_ch2, (void*) isr_dma1_ch3, @@ -143,7 +137,7 @@ ISR_VECTORS const void *interrupt_vector[] = { (void*) isr_usb_lp_can1_rx0, (void*) isr_can1_rx1, (void*) isr_can1_sce, - (void*) isr_exti9_5, + (void*) isr_exti, (void*) isr_tim1_brk, (void*) isr_tim1_up, (void*) isr_tim1_trg_com, @@ -160,7 +154,7 @@ ISR_VECTORS const void *interrupt_vector[] = { (void*) isr_usart1, (void*) isr_usart2, (void*) isr_usart3, - (void*) isr_exti15_10, + (void*) isr_exti, (void*) isr_rtc_alarm, (void*) isr_usb_wakeup, (void*) isr_tim8_brk,