Skip to content
Snippets Groups Projects
Commit 84880c1f authored by Hauke Petersen's avatar Hauke Petersen
Browse files

cpu/stm32f0: adapted GPIO driver

parent 363eb58c
No related branches found
No related tags found
No related merge requests found
...@@ -44,6 +44,31 @@ typedef uint32_t gpio_t; ...@@ -44,6 +44,31 @@ typedef uint32_t gpio_t;
*/ */
#define GPIO_PIN(x, y) ((GPIOA_BASE + (x << 10)) | y) #define GPIO_PIN(x, y) ((GPIOA_BASE + (x << 10)) | y)
/**
* @brief Generate GPIO mode bitfields
*
* We use 5 bit to encode the mode:
* - bit 0+1: pin mode (input / output)
* - bit 2+3: pull resistor configuration
* - bit 4: output type (0: push-pull, 1: open-drain)
*/
#define GPIO_MODE(io, pr, ot) ((io << 0) | (pr << 2) | (ot << 4))
/**
* @brief Override GPIO mode options
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(0, 0, 0), /**< input w/o pull R */
GPIO_IN_PD = GPIO_MODE(0, 2, 0), /**< input with pull-down */
GPIO_IN_PU = GPIO_MODE(0, 1, 0), /**< input with pull-up */
GPIO_OUT = GPIO_MODE(1, 0, 0), /**< push-pull output */
GPIO_OD = GPIO_MODE(1, 0, 1), /**< open-drain w/o pull R */
GPIO_OD_PU = GPIO_MODE(1, 1, 1) /**< open-drain with pull-up */
} gpio_mode_t;
/** @} */
/** /**
* @brief Override flank configuration values * @brief Override flank configuration values
* @{ * @{
......
...@@ -61,31 +61,32 @@ static inline int _pin_num(gpio_t pin) ...@@ -61,31 +61,32 @@ static inline int _pin_num(gpio_t pin)
return (pin & 0x0f); return (pin & 0x0f);
} }
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); GPIO_TypeDef *port = _port(pin);
int pin_num = _pin_num(pin); int pin_num = _pin_num(pin);
/* enable clock */ /* enable clock */
RCC->AHBENR |= (RCC_AHBENR_GPIOAEN << _port_num(pin)); RCC->AHBENR |= (RCC_AHBENR_GPIOAEN << _port_num(pin));
/* configure pull register */
port->PUPDR &= ~(3 << (2 * pin_num)); /* set mode */
port->PUPDR |= (pullup << (2 * pin_num)); port->MODER &= ~(0x3 << (2 * pin_num));
/* set direction */ port->MODER |= ((mode & 0x3) << (2 * pin_num));
if (dir == GPIO_DIR_OUT) { /* set pull resistor configuration */
port->MODER &= ~(3 << (2 * pin_num)); /* set pin to output mode */ port->PUPDR &= ~(0x3 << (2 * pin_num));
port->MODER |= (1 << (2 * pin_num)); port->PUPDR |= (((mode >> 2) & 0x3) << (2 * pin_num));
port->OTYPER &= ~(1 << pin_num); /* set to push-pull */ /* set output mode */
port->OSPEEDR |= (3 << (2 * pin_num)); /* set to high speed */ port->OTYPER &= ~(1 << pin_num);
port->ODR &= ~(1 << pin_num); /* set pin to low signal */ port->OTYPER |= (((mode >> 4) & 0x1) << pin_num);
} /* finally set pin speed to maximum and reset output */
else { port->OSPEEDR |= (3 << (2 * pin_num));
port->MODER &= ~(3 << (2 * pin_num)); /* configure pin as input */ port->BRR = (1 << pin_num);
}
return 0; return 0;
} }
int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb, void *arg) 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); int pin_num = _pin_num(pin);
int port_num = _port_num(pin); int port_num = _port_num(pin);
...@@ -98,7 +99,7 @@ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb ...@@ -98,7 +99,7 @@ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN; RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
/* initialize pin as input */ /* initialize pin as input */
gpio_init(pin, GPIO_DIR_IN, pullup); gpio_init(pin, mode);
/* enable global pin interrupt */ /* enable global pin interrupt */
if (pin_num < 2) { if (pin_num < 2) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment