drv_uart.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2013-05-18 Bernard The first version for LPC40xx
  9. * 2014-07-18 ArdaFu Port to TM4C129X
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include <rtdevice.h>
  14. #include "board.h"
  15. #include "inc/hw_memmap.h"
  16. #include "driverlib/sysctl.h"
  17. #include "driverlib/gpio.h"
  18. #include "driverlib/uart.h"
  19. #include "driverlib/pin_map.h"
  20. #include "driverlib/interrupt.h"
  21. #include "driverlib/rom_map.h"
  22. typedef struct hw_uart_device
  23. {
  24. uint32_t hw_base; // base address
  25. }hw_uart_t;
  26. #define mUartGetHwPtr(serial) ((hw_uart_t*)(serial->parent.user_data))
  27. static rt_err_t hw_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  28. {
  29. uint32_t config = 0;
  30. hw_uart_t* uart;
  31. RT_ASSERT(serial != RT_NULL);
  32. uart = mUartGetHwPtr(serial);
  33. MAP_UARTDisable(uart->hw_base);
  34. // build UART Configuration parameter structure
  35. switch(cfg->data_bits)
  36. {
  37. case DATA_BITS_9:
  38. // enable 9bit address mode and set DATA_BIT_8
  39. MAP_UART9BitEnable(uart->hw_base);
  40. case DATA_BITS_8:
  41. config |= UART_CONFIG_WLEN_8;
  42. break;
  43. case DATA_BITS_7:
  44. config |= UART_CONFIG_WLEN_7;
  45. break;
  46. case DATA_BITS_6:
  47. config |= UART_CONFIG_WLEN_6;
  48. break;
  49. case DATA_BITS_5:
  50. config |= UART_CONFIG_WLEN_5;
  51. break;
  52. default:
  53. RT_ASSERT(0);
  54. break;
  55. }
  56. switch(cfg->parity)
  57. {
  58. case PARITY_ODD:
  59. config |= UART_CONFIG_PAR_ODD;
  60. break;
  61. case PARITY_EVEN:
  62. config |= UART_CONFIG_PAR_EVEN;
  63. break;
  64. case PARITY_NONE:
  65. config |= UART_CONFIG_PAR_NONE;
  66. break;
  67. default:
  68. RT_ASSERT(0);
  69. break;
  70. }
  71. switch(cfg->stop_bits)
  72. {
  73. case STOP_BITS_1:
  74. config |= UART_CONFIG_STOP_ONE;
  75. break;
  76. case STOP_BITS_2:
  77. config |= UART_CONFIG_STOP_TWO;
  78. break;
  79. default:
  80. RT_ASSERT(0);
  81. break;
  82. }
  83. // Initialize UART0 peripheral with given to corresponding parameter
  84. MAP_UARTConfigSetExpClk(uart->hw_base, SystemCoreClock, cfg->baud_rate, config);
  85. MAP_UARTFIFOEnable(uart->hw_base);
  86. // Enable the UART.
  87. MAP_UARTEnable(uart->hw_base);
  88. return RT_EOK;
  89. }
  90. static rt_err_t hw_control(struct rt_serial_device *serial, int cmd, void *arg)
  91. {
  92. hw_uart_t* uart;
  93. RT_ASSERT(serial != RT_NULL);
  94. uart = mUartGetHwPtr(serial);
  95. switch (cmd)
  96. {
  97. case RT_DEVICE_CTRL_CLR_INT:
  98. /* disable rx irq */
  99. MAP_UARTIntDisable(uart->hw_base, UART_INT_RX | UART_INT_RT);
  100. break;
  101. case RT_DEVICE_CTRL_SET_INT:
  102. /* enable rx irq */
  103. MAP_UARTIntEnable(uart->hw_base, UART_INT_RX | UART_INT_RT);
  104. break;
  105. }
  106. return RT_EOK;
  107. }
  108. static int hw_putc(struct rt_serial_device *serial, char c)
  109. {
  110. hw_uart_t* uart;
  111. RT_ASSERT(serial != RT_NULL);
  112. uart = mUartGetHwPtr(serial);
  113. MAP_UARTCharPut(uart->hw_base, *((uint8_t *)&c));
  114. return 1;
  115. }
  116. static int hw_getc(struct rt_serial_device *serial)
  117. {
  118. hw_uart_t* uart;
  119. RT_ASSERT(serial != RT_NULL);
  120. uart = mUartGetHwPtr(serial);
  121. return MAP_UARTCharGetNonBlocking(uart->hw_base);
  122. }
  123. static const struct rt_uart_ops hw_uart_ops =
  124. {
  125. hw_configure,
  126. hw_control,
  127. hw_putc,
  128. hw_getc,
  129. };
  130. #if defined(RT_USING_UART0)
  131. /* UART0 device driver structure */
  132. struct rt_serial_device serial0;
  133. hw_uart_t uart0 =
  134. {
  135. UART0_BASE,
  136. };
  137. void UART0_IRQHandler(void)
  138. {
  139. uint32_t intsrc;
  140. hw_uart_t *uart = &uart0;
  141. /* enter interrupt */
  142. rt_interrupt_enter();
  143. /* Determine the interrupt source */
  144. intsrc = MAP_UARTIntStatus(uart->hw_base, true);
  145. // Receive Data Available or Character time-out
  146. if (intsrc & (UART_INT_RX | UART_INT_RT))
  147. {
  148. MAP_UARTIntClear(uart->hw_base, intsrc);
  149. rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND);
  150. }
  151. /* leave interrupt */
  152. rt_interrupt_leave();
  153. }
  154. #endif
  155. int rt_hw_uart_init(void)
  156. {
  157. hw_uart_t* uart;
  158. struct serial_configure config;
  159. config.baud_rate = BAUD_RATE_115200;
  160. config.bit_order = BIT_ORDER_LSB;
  161. config.data_bits = DATA_BITS_8;
  162. config.parity = PARITY_NONE;
  163. config.stop_bits = STOP_BITS_1;
  164. config.invert = NRZ_NORMAL;
  165. config.bufsz = RT_SERIAL_RB_BUFSZ;
  166. #ifdef RT_USING_UART0
  167. uart = &uart0;
  168. serial0.ops = &hw_uart_ops;
  169. serial0.config = config;
  170. MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  171. MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
  172. MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
  173. MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  174. MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  175. /* preemption = 1, sub-priority = 1 */
  176. //IntPrioritySet(INT_UART0, ((0x01 << 5) | 0x01));
  177. /* Enable Interrupt for UART channel */
  178. UARTIntRegister(uart->hw_base, UART0_IRQHandler);
  179. MAP_IntEnable(INT_UART0);
  180. MAP_UARTEnable(uart->hw_base);
  181. /* register UART0 device */
  182. rt_hw_serial_register(&serial0, "uart0",
  183. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  184. uart);
  185. #endif
  186. return 0;
  187. }
  188. INIT_BOARD_EXPORT(rt_hw_uart_init);