drv_pin.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-03-24 YangXi the first version.
  9. */
  10. #include "drv_pin.h"
  11. #include "fsl_common.h"
  12. #include "fsl_gpio.h"
  13. #include "fsl_port.h"
  14. #include "fsl_inputmux.h"
  15. #ifdef RT_USING_PIN
  16. #define GET_GPIO_PORT(x) ((x) / 32)
  17. #define GET_GPIO_PIN(x) ((x) % 32)
  18. static struct rt_pin_ops mcx_pin_ops;
  19. static GPIO_Type *GPIO_TYPE_TBL[] = {GPIO0, GPIO1, GPIO2, GPIO3};
  20. static PORT_Type *PORT_TYPE_TBL[] = {PORT0, PORT1, PORT2, PORT3};
  21. static IRQn_Type IRQ_TYPE_TBL[] = {GPIO0_IRQn, GPIO1_IRQn, GPIO2_IRQn, GPIO3_IRQn};
  22. #define PIN2GPIO(x) GPIO_TYPE_TBL[GET_GPIO_PORT(x)]
  23. #define PIN2PORT(x) PORT_TYPE_TBL[GET_GPIO_PORT(x)]
  24. #define PIN2IRQ(x) IRQ_TYPE_TBL[GET_GPIO_PORT(x)]
  25. struct rt_pin_irq_hdr pin_irq_hdr_tab[32*4] = {0};
  26. static void mcx_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
  27. {
  28. port_pin_config_t port_pin_config = {0};
  29. gpio_pin_config_t gpio_pin_config = {0};
  30. port_pin_config.mux = kPORT_MuxAlt0;
  31. switch (mode)
  32. {
  33. case PIN_MODE_OUTPUT:
  34. {
  35. gpio_pin_config.pinDirection = kGPIO_DigitalOutput;
  36. port_pin_config.pullSelect = kPORT_PullDisable;
  37. port_pin_config.inputBuffer = kPORT_InputBufferEnable;
  38. }
  39. break;
  40. case PIN_MODE_INPUT:
  41. {
  42. gpio_pin_config.pinDirection = kGPIO_DigitalInput;
  43. port_pin_config.pullSelect = kPORT_PullDisable;
  44. port_pin_config.inputBuffer = kPORT_InputBufferEnable;
  45. }
  46. break;
  47. case PIN_MODE_INPUT_PULLDOWN:
  48. {
  49. gpio_pin_config.pinDirection = kGPIO_DigitalInput;
  50. port_pin_config.pullSelect = kPORT_PullDown;
  51. port_pin_config.pullValueSelect = kPORT_LowPullResistor;
  52. port_pin_config.inputBuffer = kPORT_InputBufferEnable;
  53. }
  54. break;
  55. case PIN_MODE_INPUT_PULLUP:
  56. {
  57. gpio_pin_config.pinDirection = kGPIO_DigitalInput;
  58. port_pin_config.pullSelect = kPORT_PullUp;
  59. port_pin_config.pullValueSelect = kPORT_LowPullResistor;
  60. port_pin_config.inputBuffer = kPORT_InputBufferEnable;
  61. }
  62. break;
  63. case PIN_MODE_OUTPUT_OD:
  64. {
  65. port_pin_config.openDrainEnable = kPORT_OpenDrainEnable;
  66. gpio_pin_config.pinDirection = kGPIO_DigitalOutput;
  67. port_pin_config.inputBuffer = kPORT_InputBufferEnable;
  68. }
  69. break;
  70. }
  71. PORT_SetPinConfig(PIN2PORT(pin), GET_GPIO_PIN(pin), &port_pin_config);
  72. GPIO_PinInit(PIN2GPIO(pin), GET_GPIO_PIN(pin) , &gpio_pin_config);
  73. }
  74. static void mcx_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
  75. {
  76. GPIO_PinWrite(PIN2GPIO(pin), GET_GPIO_PIN(pin), value);
  77. }
  78. static rt_ssize_t mcx_pin_read(rt_device_t dev, rt_base_t pin)
  79. {
  80. return GPIO_PinRead(PIN2GPIO(pin), GET_GPIO_PIN(pin));
  81. }
  82. rt_inline void pin_irq_handler(uint8_t gpio_idx)
  83. {
  84. int i;
  85. rt_interrupt_enter();
  86. uint32_t INTFLAG = GPIO_GpioGetInterruptFlags(GPIO_TYPE_TBL[gpio_idx]);
  87. GPIO_GpioClearInterruptFlags(GPIO_TYPE_TBL[gpio_idx], INTFLAG);
  88. for(i=0; i<ARRAY_SIZE(pin_irq_hdr_tab); i++)
  89. {
  90. if((INTFLAG & (1<<GET_GPIO_PIN(pin_irq_hdr_tab[i].pin))) && pin_irq_hdr_tab[i].hdr && (GET_GPIO_PORT(pin_irq_hdr_tab[i].pin)) == gpio_idx)
  91. {
  92. pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
  93. }
  94. }
  95. rt_interrupt_leave();
  96. }
  97. void GPIO0_IRQHandler(void)
  98. {
  99. pin_irq_handler(0);
  100. }
  101. void GPIO1_IRQHandler(void)
  102. {
  103. pin_irq_handler(1);
  104. }
  105. void GPIO2_IRQHandler(void)
  106. {
  107. pin_irq_handler(2);
  108. }
  109. void GPIO3_IRQHandler(void)
  110. {
  111. pin_irq_handler(3);
  112. }
  113. static rt_err_t mcx_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
  114. {
  115. switch (mode)
  116. {
  117. case PIN_IRQ_MODE_RISING:
  118. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptRisingEdge);
  119. break;
  120. case PIN_IRQ_MODE_FALLING:
  121. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptFallingEdge);
  122. break;
  123. case PIN_IRQ_MODE_RISING_FALLING:
  124. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptEitherEdge);
  125. break;
  126. case PIN_IRQ_MODE_HIGH_LEVEL:
  127. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptLogicOne);
  128. break;
  129. case PIN_IRQ_MODE_LOW_LEVEL:
  130. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptLogicZero);
  131. break;
  132. }
  133. pin_irq_hdr_tab[pin].pin = pin;
  134. pin_irq_hdr_tab[pin].mode = mode;
  135. pin_irq_hdr_tab[pin].hdr = hdr;
  136. pin_irq_hdr_tab[pin].args = args;
  137. return RT_EOK;
  138. }
  139. static rt_err_t mcx_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  140. {
  141. GPIO_SetPinInterruptConfig(PIN2GPIO(pin), GET_GPIO_PIN(pin), kGPIO_InterruptStatusFlagDisabled);
  142. return RT_EOK;
  143. }
  144. static rt_err_t mcx_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
  145. {
  146. if(enabled)
  147. {
  148. EnableIRQ(PIN2IRQ(pin));
  149. }
  150. else
  151. {
  152. DisableIRQ(PIN2IRQ(pin));
  153. }
  154. return RT_EOK;
  155. }
  156. int rt_hw_pin_init(void)
  157. {
  158. int ret = RT_EOK;
  159. mcx_pin_ops.pin_mode = mcx_pin_mode;
  160. mcx_pin_ops.pin_read = mcx_pin_read;
  161. mcx_pin_ops.pin_write = mcx_pin_write;
  162. mcx_pin_ops.pin_attach_irq = mcx_pin_attach_irq;
  163. mcx_pin_ops.pin_detach_irq = mcx_pin_detach_irq;
  164. mcx_pin_ops.pin_irq_enable = mcx_pin_irq_enable;
  165. mcx_pin_ops.pin_get = RT_NULL,
  166. ret = rt_device_pin_register("pin", &mcx_pin_ops, RT_NULL);
  167. return ret;
  168. }
  169. INIT_BOARD_EXPORT(rt_hw_pin_init);
  170. #endif /*RT_USING_PIN */
  171. // end file