gpio.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "gpio.h"
  2. #include "FreeRTOS.h"
  3. #include "task.h"
  4. gpio_pindef_t gpio_pins[] = {
  5. GPIO_TABLE(EXPAND_AS_DEFS)
  6. };
  7. void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf) {
  8. uint8_t shift;
  9. shift = pin * 2;
  10. port->MODER &= ~(GPIO_MODER_MASK << shift);
  11. port->MODER |= (uint32_t)((conf >> GPIO_MODE_CFG_SHIFT) & GPIO_MODER_MASK) << shift;
  12. port->OTYPER &= ~(GPIO_TYPER_MASK << pin);
  13. port->OTYPER |= (uint32_t)((conf >> GPIO_TYPE_CFG_SHIFT) & GPIO_TYPER_MASK) << pin;
  14. port->OSPEEDR &= ~(GPIO_SPEEDR_MASK << shift);
  15. port->OSPEEDR |= (uint32_t)((conf >> GPIO_SPEED_CFG_SHIFT) & GPIO_SPEEDR_MASK) << shift;
  16. port->PUPDR &= ~(GPIO_PUPDR_MASK << shift);
  17. port->PUPDR |= (uint32_t)((conf >> GPIO_PUPD_CFG_SHIFT) & GPIO_PUPDR_MASK) << shift;
  18. }
  19. void gpio_connect_af(gpio_t id, uint8_t af_n) {
  20. gpio_pindef_t *pin = &gpio_pins[id];
  21. uint8_t shift;
  22. if (pin->pin < 8) {
  23. shift = pin->pin * 4;
  24. pin->port->AFR[0] &= ~((uint32_t)GPIO_AFR_MASK << shift);
  25. pin->port->AFR[0] |= af_n << shift;
  26. }
  27. else {
  28. shift = (pin->pin - 8) * 4;
  29. pin->port->AFR[1] &= ~((uint32_t)GPIO_AFR_MASK << shift);
  30. pin->port->AFR[1] |= af_n << shift;
  31. }
  32. }
  33. /*
  34. * TODO add analog flag and setup ADC pins in a proper way
  35. */
  36. void gpio_set_config(gpio_t id) {
  37. gpio_pindef_t *pin = &gpio_pins[id];
  38. if (pin->flags & GPIO_AF) {
  39. uint8_t af_n = (uint8_t)(pin->flags >> _GPIO_AF_SHIFT);
  40. gpio_connect_af(id, af_n);
  41. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_AF_CFG |
  42. GPIO_SPEED_HIGH_CFG);
  43. }
  44. else if (pin->flags & GPIO_IN)
  45. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG |
  46. GPIO_SPEED_HIGH_CFG);
  47. else if (pin->flags & GPIO_IN_PU) {
  48. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | GPIO_PU_CFG |
  49. GPIO_SPEED_HIGH_CFG);
  50. gpio_set(id, pin->flags & GPIO_SET);
  51. }
  52. else if (pin->flags & GPIO_IN_PD) {
  53. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_IN_CFG | GPIO_PD_CFG |
  54. GPIO_SPEED_HIGH_CFG);
  55. gpio_set(id, pin->flags & GPIO_SET);
  56. }
  57. else if (pin->flags & GPIO_OUT) {
  58. gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_OUT_CFG |
  59. ((pin->flags & GPIO_OD) ?
  60. GPIO_TYPE_OD_CFG : GPIO_TYPE_PP_CFG) |
  61. GPIO_SPEED_HIGH_CFG);
  62. gpio_set(id, pin->flags & GPIO_SET);
  63. }
  64. }
  65. void gpio_init(void) {
  66. uint32_t i;
  67. GPIO_DeInit(GPIOA);
  68. GPIO_DeInit(GPIOB);
  69. GPIO_DeInit(GPIOC);
  70. GPIO_DeInit(GPIOD);
  71. GPIO_DeInit(GPIOE);
  72. // configure clocks
  73. RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
  74. RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
  75. RCC_AHB1ENR_GPIOEEN;
  76. // configure gpios
  77. for (i = 0; i < GPIO_TOTAL_COUNT; i++) {
  78. if (gpio_pins[i].flags & GPIO_NOINIT)
  79. continue;
  80. else {
  81. gpio_set_config((gpio_t)i);
  82. }
  83. }
  84. }
  85. void gpio_set(gpio_t pin, bool value) {
  86. if (gpio_pins[pin].flags & GPIO_INV)
  87. value = !value;
  88. if (value)
  89. gpio_pins[pin].port->BSRRL = 1 << gpio_pins[pin].pin;
  90. else
  91. gpio_pins[pin].port->BSRRH = 1 << gpio_pins[pin].pin;
  92. }
  93. void gpio_invert_output(gpio_t pin) {
  94. gpio_pins[pin].port->ODR ^= 1 << gpio_pins[pin].pin;
  95. }
  96. bool gpio_get(gpio_t pin) {
  97. bool value;
  98. if (gpio_pins[pin].flags & GPIO_NOINIT) {
  99. return false;
  100. }
  101. else {
  102. value = (gpio_pins[pin].port->IDR & (1 << gpio_pins[pin].pin)) >> gpio_pins[pin].pin;
  103. return (gpio_pins[pin].flags & GPIO_INV) ? !value : value;
  104. }
  105. }
  106. bool gpio_is_output(gpio_t pin) {
  107. return (gpio_pins[pin].flags & GPIO_OUT) ? true : false;
  108. }
  109. void gpio_set_direction(gpio_t pin, bool out) {
  110. if (out) {
  111. gpio_pins[pin].flags &= ~(GPIO_IN | GPIO_IN_PU);
  112. gpio_pins[pin].flags |= GPIO_OUT;
  113. }
  114. else {
  115. gpio_pins[pin].flags &= ~(GPIO_OUT | GPIO_OD);
  116. gpio_pins[pin].flags |= GPIO_IN;
  117. }
  118. gpio_set_config(pin);
  119. }
  120. void gpio_test() {
  121. }
  122. exti_handler_t exti_handlers[EXTI_MAX_HANDLERS];
  123. uint8_t exti_handlers_count = 0;
  124. void gpio_enable_exti(gpio_t pin, void (*handler)(void)) {
  125. EXTI->IMR = 0x00000000;
  126. EXTI->EMR = 0x00000000;
  127. EXTI->RTSR = 0x00000000;
  128. EXTI->FTSR = 0x00000000;
  129. EXTI->PR = 0x007FFFFF;
  130. uint8_t port_num, pin_num;
  131. port_num = ((uint32_t)gpio_pins[pin].port - (uint32_t)GPIOA) / 0x400;
  132. pin_num = gpio_pins[pin].pin;
  133. #if defined(STM32F1)
  134. AFIO->EXTICR[pin_num >> 2] &= ~(0xf << (pin_num & 3));
  135. AFIO->EXTICR[pin_num >> 2] |= port_num << (pin_num & 3);
  136. #else
  137. SYSCFG_EXTILineConfig(port_num, pin_num);
  138. #endif
  139. EXTI->IMR |= 1 << pin_num;
  140. EXTI->RTSR |= 1 << pin_num;
  141. EXTI->FTSR |= 1 << pin_num;
  142. if (pin_num < 5) {
  143. NVIC_SetPriority((IRQn_Type)(EXTI0_IRQn + pin_num), NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0));
  144. NVIC_EnableIRQ((IRQn_Type)(EXTI0_IRQn + pin_num));
  145. }
  146. else if (pin_num < 10) {
  147. NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0));
  148. NVIC_EnableIRQ(EXTI9_5_IRQn);
  149. }
  150. else {
  151. NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0));
  152. NVIC_EnableIRQ(EXTI15_10_IRQn);
  153. }
  154. if (exti_handlers_count < EXTI_MAX_HANDLERS) {
  155. exti_handlers[exti_handlers_count].gpio = gpio_pins + pin;
  156. exti_handlers[exti_handlers_count].handler = handler;
  157. exti_handlers_count++;
  158. }
  159. }
  160. void EXTI_IRQHandler(void) {
  161. int i;
  162. exti_handler_t *h;
  163. for (i = 0; i < exti_handlers_count; i++) {
  164. h = exti_handlers + i;
  165. if (EXTI->PR & (1 << h->gpio->pin)) {
  166. h->handler();
  167. EXTI->PR = (1 << h->gpio->pin);
  168. }
  169. }
  170. }