drv_uart.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * File : uart.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 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://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2013-05-27 Grissiom port to RM48x50
  13. */
  14. /* welcome, if you open this file, you may want to see uart driver code.
  15. * However, TI call it Serial Communication Interface(SCI) and all the low
  16. * level API is prefixed by "sci". To avoid messive renaming, I want to keep
  17. * with TI and call all the things SCI. You could safely substitude the word
  18. * "sci" with "uart". Enjoy. */
  19. #include <rthw.h>
  20. #include <rtthread.h>
  21. #include <rtdevice.h>
  22. #include <reg_sci.h>
  23. /* bring from sci.h */
  24. enum sciIntFlags
  25. {
  26. SCI_FE_INT = 0x04000000U, /* framing error */
  27. SCI_OE_INT = 0x02000000U, /* overrun error */
  28. SCI_PE_INT = 0x01000000U, /* parity error */
  29. SCI_RX_INT = 0x00000200U, /* receive buffer ready */
  30. SCI_TX_INT = 0x00000100U, /* transmit buffer ready */
  31. SCI_WAKE_INT = 0x00000002U, /* wakeup */
  32. SCI_BREAK_INT = 0x00000001U /* break detect */
  33. };
  34. /* LIN1 High level interrupt. Change this if you set a different channel in
  35. * HALCoGen. */
  36. #define SCI_INT_VEC 14
  37. #define VCLK_HZ 100000000L
  38. static rt_err_t _configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  39. {
  40. /** - global control 1 */
  41. rt_uint32_t gcr1 = (1U << 25U) /* enable transmit */
  42. | (1U << 24U) /* enable receive */
  43. | (1U << 5U) /* internal clock (device has no clock pin) */
  44. | (1U << 1U); /* asynchronous timing mode */
  45. if (cfg->stop_bits == STOP_BITS_2)
  46. gcr1 |= (1U << 4U); /* number of stop bits */
  47. else if (cfg->stop_bits != STOP_BITS_1)
  48. return -RT_ERROR;
  49. if (cfg->parity == PARITY_EVEN)
  50. {
  51. gcr1 |= (1U << 3U) | (1U << 2U);
  52. }
  53. else if (cfg->parity == PARITY_ODD)
  54. {
  55. gcr1 |= (0U << 3U) | (1U << 2U);
  56. }
  57. /** - bring SCI out of reset */
  58. scilinREG->GCR0 = 1U;
  59. /** - Disable all interrupts */
  60. scilinREG->CLRINT = 0xFFFFFFFFU;
  61. scilinREG->CLRINTLVL = 0xFFFFFFFFU;
  62. scilinREG->GCR1 = gcr1;
  63. /** - set baudrate */
  64. scilinREG->BRS = VCLK_HZ/16/cfg->baud_rate - 1; /* baudrate */
  65. /** - transmission length */
  66. scilinREG->FORMAT = cfg->data_bits - 1; /* length */
  67. /** - set SCI pins functional mode */
  68. scilinREG->FUN = (1U << 2U) /* tx pin */
  69. | (1U << 1U) /* rx pin */
  70. | (0U); /* clk pin */
  71. /** - set SCI pins default output value */
  72. scilinREG->DOUT = (0U << 2U) /* tx pin */
  73. | (0U << 1U) /* rx pin */
  74. | (0U); /* clk pin */
  75. /** - set SCI pins output direction */
  76. scilinREG->DIR = (0U << 2U) /* tx pin */
  77. | (0U << 1U) /* rx pin */
  78. | (0U); /* clk pin */
  79. /** - set SCI pins open drain enable */
  80. scilinREG->ODR = (0U << 2U) /* tx pin */
  81. | (0U << 1U) /* rx pin */
  82. | (0U); /* clk pin */
  83. /** - set SCI pins pullup/pulldown enable */
  84. scilinREG->PD = (0U << 2U) /* tx pin */
  85. | (0U << 1U) /* rx pin */
  86. | (0U); /* clk pin */
  87. /** - set SCI pins pullup/pulldown select */
  88. scilinREG->PSL = (1U << 2U) /* tx pin */
  89. | (1U << 1U) /* rx pin */
  90. | (1U); /* clk pin */
  91. /** - set interrupt level */
  92. scilinREG->SETINTLVL = (0U << 26U) /* Framing error */
  93. | (0U << 25U) /* Overrun error */
  94. | (0U << 24U) /* Parity error */
  95. | (0U << 9U) /* Receive */
  96. | (0U << 8U) /* Transmit */
  97. | (0U << 1U) /* Wakeup */
  98. | (0U); /* Break detect */
  99. /** - set interrupt enable */
  100. scilinREG->SETINT = (0U << 26U) /* Framing error */
  101. | (0U << 25U) /* Overrun error */
  102. | (0U << 24U) /* Parity error */
  103. | (1U << 9U) /* Receive */
  104. | (0U << 1U) /* Wakeup */
  105. | (0U); /* Break detect */
  106. /** - Finaly start SCILIN */
  107. scilinREG->GCR1 |= (1U << 7U);
  108. return RT_EOK;
  109. }
  110. static rt_err_t _control(struct rt_serial_device *serial, int cmd, void *arg)
  111. {
  112. sciBASE_t *sci = (sciBASE_t*)serial->parent.user_data;
  113. switch (cmd)
  114. {
  115. case RT_DEVICE_CTRL_CLR_INT:
  116. /* disable rx irq */
  117. sci->CLRINT = SCI_RX_INT;
  118. break;
  119. case RT_DEVICE_CTRL_SET_INT:
  120. /* enable rx irq */
  121. sci->SETINT = SCI_RX_INT;
  122. break;
  123. }
  124. return RT_EOK;
  125. }
  126. static int _putc(struct rt_serial_device *serial, char c)
  127. {
  128. sciBASE_t *sci = (sciBASE_t*)serial->parent.user_data;
  129. while ((sci->FLR & SCI_TX_INT) == 0U)
  130. ;
  131. sci->TD = c;
  132. return 1;
  133. }
  134. static int _getc(struct rt_serial_device *serial)
  135. {
  136. sciBASE_t *sci = (sciBASE_t*)serial->parent.user_data;
  137. if (sci->FLR & (1<<9))
  138. return (sci->RD & 0x000000FFU);
  139. else
  140. return -1;
  141. }
  142. static const struct rt_uart_ops _sci_ops =
  143. {
  144. _configure,
  145. _control,
  146. _putc,
  147. _getc,
  148. };
  149. static void _irq_wrapper(int vector, void *param)
  150. {
  151. rt_hw_serial_isr((struct rt_serial_device*)param, RT_SERIAL_EVENT_RX_IND);
  152. }
  153. static struct rt_serial_device _sci2_serial;
  154. void rt_hw_uart_init(void)
  155. {
  156. struct serial_configure config;
  157. /* fake configuration */
  158. config.baud_rate = BAUD_RATE_115200;
  159. config.bit_order = BIT_ORDER_LSB;
  160. config.data_bits = DATA_BITS_8;
  161. config.parity = PARITY_NONE;
  162. config.stop_bits = STOP_BITS_1;
  163. config.invert = NRZ_NORMAL;
  164. config.bufsz = RT_SERIAL_RB_BUFSZ;
  165. _sci2_serial.ops = &_sci_ops;
  166. _sci2_serial.config = config;
  167. rt_hw_serial_register(&_sci2_serial, "sci2",
  168. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
  169. (void*)scilinREG);
  170. rt_device_control(&_sci2_serial.parent, RT_DEVICE_CTRL_SET_INT, 0);
  171. rt_hw_interrupt_install(SCI_INT_VEC, _irq_wrapper, &_sci2_serial, "sci2");
  172. rt_hw_interrupt_umask(SCI_INT_VEC);
  173. }