gpio.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "gpio.h"
  2. gpio_pindef_t gpio_pins[] = {
  3. GPIO_TABLE(EXPAND_AS_DEFS)
  4. };
  5. void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf) {
  6. uint8_t shift;
  7. shift = pin * 2;
  8. port->MODER &= ~(GPIO_MODER_MASK << shift);
  9. port->MODER |= (uint32_t)((conf >> GPIO_MODE_CFG_SHIFT) & GPIO_MODER_MASK) << shift;
  10. port->OTYPER &= ~(GPIO_TYPER_MASK << pin);
  11. port->OTYPER |= (uint32_t)((conf >> GPIO_TYPE_CFG_SHIFT) & GPIO_TYPER_MASK) << pin;
  12. port->OSPEEDR &= ~(GPIO_SPEEDR_MASK << shift);
  13. port->OSPEEDR |= (uint32_t)((conf >> GPIO_SPEED_CFG_SHIFT) & GPIO_SPEEDR_MASK) << shift;
  14. port->PUPDR &= ~(GPIO_PUPDR_MASK << shift);
  15. port->PUPDR |= (uint32_t)((conf >> GPIO_PUPD_CFG_SHIFT) & GPIO_PUPDR_MASK) << shift;
  16. }
  17. void gpio_connect_af(gpio_t id, uint8_t af_n) {
  18. gpio_pindef_t *pin = &gpio_pins[id];
  19. uint8_t shift;
  20. if (pin->pin < 8) {
  21. shift = pin->pin * 4;
  22. pin->port->AFR[0] &= ~((uint32_t)GPIO_AFR_MASK << shift);
  23. pin->port->AFR[0] |= af_n << shift;
  24. }
  25. else {
  26. shift = (pin->pin - 8) * 4;
  27. pin->port->AFR[1] &= ~((uint32_t)GPIO_AFR_MASK << shift);
  28. pin->port->AFR[1] |= af_n << shift;
  29. }
  30. }
  31. /*
  32. * TODO add analog flag and setup ADC pins in a proper way
  33. */
  34. static void gpio_set_config(gpio_t id) {
  35. gpio_pindef_t *pin = &gpio_pins[id];
  36. if (pin->flags & GPIO_AF) {
  37. uint8_t af_n = (uint8_t)(pin->flags >> _GPIO_AF_SHIFT);
  38. gpio_connect_af(id, af_n);
  39. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_AF_CFG |
  40. GPIO_SPEED_HIGH_CFG);
  41. }
  42. else if (pin->flags & GPIO_IN)
  43. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG |
  44. GPIO_SPEED_HIGH_CFG);
  45. else if (pin->flags & GPIO_IN_PU) {
  46. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | GPIO_PU_CFG |
  47. GPIO_SPEED_HIGH_CFG);
  48. gpio_set(id, pin->flags & GPIO_SET);
  49. }
  50. else if (pin->flags & GPIO_OUT) {
  51. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_OUT_CFG |
  52. ((pin->flags & GPIO_OD) ?
  53. GPIO_TYPE_OD_CFG : GPIO_TYPE_PP_CFG) |
  54. GPIO_SPEED_HIGH_CFG);
  55. gpio_set(id, pin->flags & GPIO_SET);
  56. }
  57. }
  58. void gpio_init(void) {
  59. uint32_t i;
  60. GPIO_DeInit(GPIOA);
  61. GPIO_DeInit(GPIOB);
  62. GPIO_DeInit(GPIOC);
  63. GPIO_DeInit(GPIOD);
  64. GPIO_DeInit(GPIOE);
  65. // configure clocks
  66. RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
  67. RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
  68. RCC_AHB1ENR_GPIOEEN;
  69. // configure gpios
  70. for (i = 0; i < GPIO_TOTAL_COUNT; i++) {
  71. if (gpio_pins[i].flags & GPIO_NOINIT)
  72. continue;
  73. else {
  74. gpio_set_config(i);
  75. }
  76. }
  77. }
  78. void gpio_set(gpio_t pin, bool value) {
  79. if (gpio_pins[pin].flags & GPIO_INV)
  80. value = !value;
  81. if (value)
  82. gpio_pins[pin].port->BSRRL = 1 << gpio_pins[pin].pin;
  83. else
  84. gpio_pins[pin].port->BSRRH = 1 << gpio_pins[pin].pin;
  85. }
  86. void gpio_invert_output(gpio_t pin) {
  87. gpio_pins[pin].port->ODR ^= 1 << gpio_pins[pin].pin;
  88. }
  89. bool gpio_get(gpio_t pin) {
  90. bool value;
  91. if (gpio_pins[pin].flags & GPIO_NOINIT) {
  92. return false;
  93. }
  94. else {
  95. value = (gpio_pins[pin].port->IDR & (1 << gpio_pins[pin].pin)) >> gpio_pins[pin].pin;
  96. return (gpio_pins[pin].flags & GPIO_INV) ? !value : value;
  97. }
  98. }
  99. bool gpio_is_output(gpio_t pin) {
  100. return (gpio_pins[pin].flags & GPIO_OUT) ? true : false;
  101. }
  102. void gpio_set_direction(gpio_t pin, bool out) {
  103. if (out) {
  104. gpio_pins[pin].flags &= ~(GPIO_IN | GPIO_IN_PU);
  105. gpio_pins[pin].flags |= GPIO_OUT;
  106. }
  107. else {
  108. gpio_pins[pin].flags &= ~(GPIO_OUT | GPIO_OD);
  109. gpio_pins[pin].flags |= GPIO_IN;
  110. }
  111. gpio_set_config(pin);
  112. }
  113. void gpio_test() {
  114. }
  115. typedef struct {
  116. gpio_pindef_t *gpio;
  117. void (*handler)(void);
  118. } exti_handler_t;