123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #include "gpio.h"
- gpio_pindef_t gpio_pins[] = {
- GPIO_TABLE(EXPAND_AS_DEFS)
- };
- void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf) {
- uint8_t shift;
- shift = pin * 2;
- port->MODER &= ~(GPIO_MODER_MASK << shift);
- port->MODER |= (uint32_t)((conf >> GPIO_MODE_CFG_SHIFT) & GPIO_MODER_MASK) << shift;
- port->OTYPER &= ~(GPIO_TYPER_MASK << pin);
- port->OTYPER |= (uint32_t)((conf >> GPIO_TYPE_CFG_SHIFT) & GPIO_TYPER_MASK) << pin;
- port->OSPEEDR &= ~(GPIO_SPEEDR_MASK << shift);
- port->OSPEEDR |= (uint32_t)((conf >> GPIO_SPEED_CFG_SHIFT) & GPIO_SPEEDR_MASK) << shift;
- port->PUPDR &= ~(GPIO_PUPDR_MASK << shift);
- port->PUPDR |= (uint32_t)((conf >> GPIO_PUPD_CFG_SHIFT) & GPIO_PUPDR_MASK) << shift;
- }
- void gpio_connect_af(gpio_t id, uint8_t af_n) {
- gpio_pindef_t *pin = &gpio_pins[id];
- uint8_t shift;
- if (pin->pin < 8) {
- shift = pin->pin * 4;
- pin->port->AFR[0] &= ~((uint32_t)GPIO_AFR_MASK << shift);
- pin->port->AFR[0] |= af_n << shift;
- }
- else {
- shift = (pin->pin - 8) * 4;
- pin->port->AFR[1] &= ~((uint32_t)GPIO_AFR_MASK << shift);
- pin->port->AFR[1] |= af_n << shift;
- }
- }
- /*
- * TODO add analog flag and setup ADC pins in a proper way
- */
- static void gpio_set_config(gpio_t id) {
- gpio_pindef_t *pin = &gpio_pins[id];
- if (pin->flags & GPIO_AF) {
- uint8_t af_n = (uint8_t)(pin->flags >> _GPIO_AF_SHIFT);
- gpio_connect_af(id, af_n);
- gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_AF_CFG |
- GPIO_SPEED_HIGH_CFG);
- }
- else if (pin->flags & GPIO_IN)
- gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG |
- GPIO_SPEED_HIGH_CFG);
- else if (pin->flags & GPIO_IN_PU) {
- gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | GPIO_PU_CFG |
- GPIO_SPEED_HIGH_CFG);
- gpio_set(id, pin->flags & GPIO_SET);
- }
- else if (pin->flags & GPIO_OUT) {
- gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_OUT_CFG |
- ((pin->flags & GPIO_OD) ?
- GPIO_TYPE_OD_CFG : GPIO_TYPE_PP_CFG) |
- GPIO_SPEED_HIGH_CFG);
- gpio_set(id, pin->flags & GPIO_SET);
- }
- }
- void gpio_init(void) {
- uint32_t i;
- GPIO_DeInit(GPIOA);
- GPIO_DeInit(GPIOB);
- GPIO_DeInit(GPIOC);
- GPIO_DeInit(GPIOD);
- GPIO_DeInit(GPIOE);
- // configure clocks
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
- RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
- RCC_AHB1ENR_GPIOEEN;
- // configure gpios
- for (i = 0; i < GPIO_TOTAL_COUNT; i++) {
- if (gpio_pins[i].flags & GPIO_NOINIT)
- continue;
- else {
- gpio_set_config(i);
- }
- }
- }
- void gpio_set(gpio_t pin, bool value) {
- if (gpio_pins[pin].flags & GPIO_INV)
- value = !value;
- if (value)
- gpio_pins[pin].port->BSRRL = 1 << gpio_pins[pin].pin;
- else
- gpio_pins[pin].port->BSRRH = 1 << gpio_pins[pin].pin;
- }
- void gpio_invert_output(gpio_t pin) {
- gpio_pins[pin].port->ODR ^= 1 << gpio_pins[pin].pin;
- }
- bool gpio_get(gpio_t pin) {
- bool value;
- if (gpio_pins[pin].flags & GPIO_NOINIT) {
- return false;
- }
- else {
- value = (gpio_pins[pin].port->IDR & (1 << gpio_pins[pin].pin)) >> gpio_pins[pin].pin;
- return (gpio_pins[pin].flags & GPIO_INV) ? !value : value;
- }
- }
- bool gpio_is_output(gpio_t pin) {
- return (gpio_pins[pin].flags & GPIO_OUT) ? true : false;
- }
- void gpio_set_direction(gpio_t pin, bool out) {
- if (out) {
- gpio_pins[pin].flags &= ~(GPIO_IN | GPIO_IN_PU);
- gpio_pins[pin].flags |= GPIO_OUT;
- }
- else {
- gpio_pins[pin].flags &= ~(GPIO_OUT | GPIO_OD);
- gpio_pins[pin].flags |= GPIO_IN;
- }
- gpio_set_config(pin);
- }
- void gpio_test() {
- }
- typedef struct {
- gpio_pindef_t *gpio;
- void (*handler)(void);
- } exti_handler_t;
|