Skip to content

Commit

Permalink
cpu/stm32l1: adapted GPIO driver
Browse files Browse the repository at this point in the history
  • Loading branch information
haukepetersen committed Mar 17, 2016
1 parent 3f478b6 commit 7d53847
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 22 deletions.
26 changes: 26 additions & 0 deletions cpu/stm32l1/include/periph_cpu.h
Expand Up @@ -45,6 +45,31 @@ typedef uint32_t gpio_t;
*/
#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 Available ports on the STM32L1 family
*/
Expand Down Expand Up @@ -106,6 +131,7 @@ typedef struct {
I2C_TypeDef *dev; /**< i2c device */
gpio_t scl; /**< scl pin number */
gpio_t sda; /**< sda pin number */
gpio_mode_t pin_mode; /**< with or without pull resistor */
gpio_af_t af; /**< I2C alternate function value */
uint8_t er_irqn; /**< error IRQ */
uint8_t ev_irqn; /**< event IRQ */
Expand Down
35 changes: 17 additions & 18 deletions cpu/stm32l1/periph/gpio.c
Expand Up @@ -63,32 +63,31 @@ 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)
int gpio_init(gpio_t pin, gpio_mode_t mode)
{
GPIO_TypeDef *port = _port(pin);
int pin_num = _pin_num(pin);

/* enable clock */
RCC->AHBENR |= (RCC_AHBENR_GPIOAEN << _port_num(pin));
/* configure pull register */
port->PUPDR &= ~(3 << (2 * pin_num));
port->PUPDR |= (pullup << (2 * pin_num));
/* set direction */
if (dir == GPIO_DIR_OUT) {
port->MODER &= ~(3 << (2 * pin_num)); /* set pin to output mode */
port->MODER |= (1 << (2 * pin_num));
port->OTYPER &= ~(1 << pin_num); /* set to push-pull */
port->OSPEEDR |= (3 << (2 * pin_num)); /* set to high speed */
port->ODR &= ~(1 << pin_num); /* set pin to low signal */
}
else {
port->MODER &= ~(3 << (2 * pin_num)); /* configure pin as input */
}

/* set mode */
port->MODER &= ~(0x3 << (2 * pin_num));
port->MODER |= ((mode & 0x3) << (2 * pin_num));
/* set pull resistor configuration */
port->PUPDR &= ~(0x3 << (2 * pin_num));
port->PUPDR |= (((mode >> 2) & 0x3) << (2 * pin_num));
/* set output mode */
port->OTYPER &= ~(1 << pin_num);
port->OTYPER |= (((mode >> 4) & 0x1) << pin_num);
/* finally set pin speed to maximum and reset output */
port->OSPEEDR |= (3 << (2 * pin_num));
port->BRR = (1 << pin_num);

return 0;
}

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);
Expand All @@ -100,7 +99,7 @@ int gpio_init_int(gpio_t pin,
/* enable the SYSCFG clock */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
/* initialize pin as input */
gpio_init(pin, GPIO_DIR_IN, pullup);
gpio_init(pin, mode);
/* enable global pin interrupt */
if (pin_num < 5) {
NVIC_EnableIRQ(EXTI0_IRQn + pin_num);
Expand Down
4 changes: 2 additions & 2 deletions cpu/stm32l1/periph/i2c.c
Expand Up @@ -97,9 +97,9 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed)
NVIC_EnableIRQ(i2c_config[dev].er_irqn);

/* configure pins */
gpio_init(i2c_config[dev].scl, GPIO_DIR_OUT, GPIO_PULLUP);
gpio_init(i2c_config[dev].scl, i2c_config[dev].pin_mode);
gpio_init_af(i2c_config[dev].scl, i2c_config[dev].af);
gpio_init(i2c_config[dev].sda, GPIO_DIR_OUT, GPIO_PULLUP);
gpio_init(i2c_config[dev].sda, i2c_config[dev].pin_mode);
gpio_init_af(i2c_config[dev].sda, i2c_config[dev].af);

/* configure device */
Expand Down
4 changes: 2 additions & 2 deletions cpu/stm32l1/periph/uart.c
Expand Up @@ -114,9 +114,9 @@ static int init_base(uart_t uart, uint32_t baudrate)
}

/* uart_configure RX and TX pins, set pin to use alternative function mode */
gpio_init(tx_pin, GPIO_DIR_OUT, GPIO_NOPULL);
gpio_init(tx_pin, GPIO_OUT);
gpio_init_af(tx_pin, af);
gpio_init(rx_pin, GPIO_DIR_IN, GPIO_NOPULL);
gpio_init(rx_pin, GPIO_IN);
gpio_init_af(rx_pin, af);

/* uart_configure UART to mode 8N1 with given baudrate */
Expand Down

0 comments on commit 7d53847

Please sign in to comment.