drv_uart.c 5.1 KB

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