No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

164 líneas
4.5 KiB

  1. /**
  2. * @ingroup PAC55xx_gpio
  3. * @brief <b>PAC55xxxx General-Purpose Input/Output (GPIO)</b>
  4. * @author @htmlonly &copy; @endhtmlonly 2019 Brian Viele <vielster@allocor.tech>
  5. * @date December 1, 2019
  6. *
  7. * This library supports the GPIO module in the PAC55xx SoC from Qorvo.
  8. *
  9. * LGPL License Terms @ref lgpl_license
  10. */
  11. /*
  12. * This file is part of the libopencm3 project.
  13. *
  14. * This library is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Lesser General Public License as published by
  16. * the Free Software Foundation, either version 3 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This library is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Lesser General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Lesser General Public License
  25. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  26. */
  27. #include <libopencm3/pac55xx/gpio.h>
  28. static uint32_t get_ccs_port_base(uint32_t gpioport) {
  29. switch (gpioport) {
  30. case GPIOA:
  31. return CCS_PORTA;
  32. case GPIOB:
  33. return CCS_PORTB;
  34. case GPIOC:
  35. return CCS_PORTC;
  36. case GPIOD:
  37. return CCS_PORTD;
  38. case GPIOE:
  39. return CCS_PORTE;
  40. case GPIOF:
  41. return CCS_PORTF;
  42. case GPIOG:
  43. return CCS_PORTG;
  44. default:
  45. return 0U;
  46. }
  47. }
  48. void gpio_mode_setup(uint32_t gpioport, gpio_mode_t mode,
  49. ccs_pull_updown_t pull_up_down, uint16_t gpios) {
  50. /* Read the current value of the register. */
  51. uint32_t reg = GPIO_MODER(gpioport);
  52. uint32_t port = get_ccs_port_base(gpioport);
  53. /* Loop through only set bits, utilize built-ins for optimized assembly. */
  54. int ffs = __builtin_ffs(gpios);
  55. while (ffs) {
  56. const int pin = ffs - 1;
  57. const int bit = (1 << pin);
  58. /* Update the cached mode value by clearing then setting values. */
  59. reg &= ~GPIO_MODER_MASK_PIN(pin);
  60. reg |= GPIO_MODER_MODE(pin, mode);
  61. /* Set the pinmux configurations for the pull-up / pull-down. */
  62. if (pull_up_down == CCS_IO_PULL_UP) {
  63. CCS_PDENR(port) &= ~bit;
  64. CCS_PUENR(port) |= bit;
  65. } else if (pull_up_down == CCS_IO_PULL_DOWN) {
  66. CCS_PUENR(port) &= ~bit;
  67. CCS_PDENR(port) |= bit;
  68. } else {
  69. CCS_PDENR(port) &= ~bit;
  70. CCS_PUENR(port) &= ~bit;
  71. }
  72. gpios ^= bit; /* Clear the bit we just serviced. */
  73. ffs = __builtin_ffs(gpios);
  74. }
  75. GPIO_MODER(gpioport) = reg;
  76. }
  77. void gpio_set_outmask(uint32_t gpioport, bool enable, uint16_t gpios) {
  78. uint32_t reg = GPIO_OUTMASKR(gpioport);
  79. if (enable) {
  80. reg |= gpios;
  81. } else {
  82. reg &= ~gpios;
  83. }
  84. GPIO_OUTMASKR(gpioport) = reg;
  85. }
  86. void gpio_set(uint32_t gpioport, uint16_t gpios) {
  87. GPIO_DOSETR(gpioport) = gpios;
  88. }
  89. void gpio_clear(uint32_t gpioport, uint16_t gpios) {
  90. GPIO_DOCLEARR(gpioport) = gpios;
  91. }
  92. uint16_t gpio_get(uint32_t gpioport, uint16_t gpios) {
  93. return GPIO_INR(gpioport) & gpios;
  94. }
  95. void gpio_set_af(uint32_t gpioport, ccs_muxsel_func_t muxsel, uint16_t gpios) {
  96. uint32_t port = get_ccs_port_base(gpioport);
  97. /* Update each of the pin configs. */
  98. uint32_t reg = CCS_MUXSELR(port);
  99. int ffs = __builtin_ffs(gpios);
  100. while (ffs) {
  101. const int pin = ffs - 1;
  102. reg &= ~CCS_MUXSELR_MASK_PIN(pin);
  103. reg |= CCS_MUXSELR_VAL(pin, muxsel);
  104. /* Set the pinmux configurations for the pull-up / pull-down. */
  105. gpios ^= (1 << pin); /* Clear the bit we just serviced. */
  106. ffs = __builtin_ffs(gpios);
  107. }
  108. CCS_MUXSELR(port) = reg;
  109. }
  110. void gpio_set_output_options(uint32_t gpioport, ccs_drive_strength_t strength,
  111. uint16_t gpios) {
  112. uint32_t port = get_ccs_port_base(gpioport);
  113. /* Update each of the pin configs. */
  114. uint32_t reg = CCS_DSR(port);
  115. int ffs = __builtin_ffs(gpios);
  116. while (ffs) {
  117. const int pin = ffs - 1;
  118. reg &= ~CCS_DSR_MASK_PIN(pin);
  119. reg |= CCS_DSR_DS_VAL(pin, strength);
  120. /* Set the pinmux configurations for the pull-up / pull-down. */
  121. gpios ^= (1 << pin); /* Clear the bit we just serviced. */
  122. ffs = __builtin_ffs(gpios);
  123. }
  124. CCS_DSR(port) = reg;
  125. }
  126. void gpio_set_schmidt_trigger(uint32_t gpioport, bool enable, uint16_t gpios) {
  127. uint32_t port = get_ccs_port_base(gpioport);
  128. /* Update each of the pin configs. */
  129. uint32_t reg = CCS_DSR(port);
  130. int ffs = __builtin_ffs(gpios);
  131. while (ffs) {
  132. const int pin = ffs - 1;
  133. if (enable) {
  134. reg |= CCS_DSR_SCHMIDT_PIN(pin);
  135. } else {
  136. reg &= ~CCS_DSR_SCHMIDT_PIN(pin);
  137. }
  138. /* Set the pinmux configurations for the pull-up / pull-down. */
  139. gpios ^= (1 << pin); /* Clear the bit we just serviced. */
  140. ffs = __builtin_ffs(gpios);
  141. }
  142. CCS_DSR(port) = reg;
  143. }