drv_sci.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-02-02 xuzhuoyi first version
  9. */
  10. #include "rtdevice.h"
  11. #include "board.h"
  12. #include "drv_sci.h"
  13. #include "F2837xD_device.h"
  14. #include "F2837xD_sci.h"
  15. typedef long off_t;
  16. #include "F2837xD_sci_io.h"
  17. #ifdef RT_USING_SERIAL
  18. #define LOG_TAG "drv.sci"
  19. /* c28x uart driver class */
  20. struct c28x_uart
  21. {
  22. const char *name;
  23. volatile struct SCI_REGS *sci_regs;
  24. struct rt_serial_device serial;
  25. };
  26. static struct c28x_uart uart_obj[3] = {0};
  27. static rt_err_t c28x_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  28. {
  29. struct c28x_uart *uart;
  30. RT_ASSERT(serial != RT_NULL);
  31. RT_ASSERT(cfg != RT_NULL);
  32. uart = (struct c28x_uart *)serial->parent.user_data;
  33. RT_ASSERT(uart != RT_NULL);
  34. EALLOW;
  35. // default config
  36. // 1 stop bit, No loopback
  37. // No parity,8 char bits,
  38. // async mode, idle-line protocol
  39. uart->sci_regs->SCICCR.all = 0x0007;
  40. // enable TX, RX, internal SCICLK,
  41. // Disable RX ERR, SLEEP, TXWAKE
  42. uart->sci_regs->SCICTL1.all = 0x0003;
  43. uart->sci_regs->SCICTL2.bit.TXINTENA = 1;
  44. uart->sci_regs->SCICTL2.bit.RXBKINTENA = 1;
  45. uart->sci_regs->SCIHBAUD.all = 0x0000; // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK).
  46. uart->sci_regs->SCILBAUD.all = 53;
  47. uart->sci_regs->SCICTL1.all = 0x0023; // Relinquish SCI from Reset
  48. switch (cfg->data_bits)
  49. {
  50. case DATA_BITS_5:
  51. uart->sci_regs->SCICCR.bit.SCICHAR = 4;
  52. break;
  53. case DATA_BITS_6:
  54. uart->sci_regs->SCICCR.bit.SCICHAR = 5;
  55. break;
  56. case DATA_BITS_7:
  57. uart->sci_regs->SCICCR.bit.SCICHAR = 6;
  58. break;
  59. case DATA_BITS_8:
  60. uart->sci_regs->SCICCR.bit.SCICHAR = 7;
  61. break;
  62. default:
  63. uart->sci_regs->SCICCR.bit.SCICHAR = 7;
  64. break;
  65. }
  66. switch (cfg->stop_bits)
  67. {
  68. case STOP_BITS_1:
  69. uart->sci_regs->SCICCR.bit.STOPBITS = 0;
  70. break;
  71. case STOP_BITS_2:
  72. uart->sci_regs->SCICCR.bit.STOPBITS = 1;
  73. break;
  74. default:
  75. uart->sci_regs->SCICCR.bit.STOPBITS = 0;
  76. break;
  77. }
  78. switch (cfg->parity)
  79. {
  80. case PARITY_NONE:
  81. uart->sci_regs->SCICCR.bit.PARITYENA = 0;
  82. break;
  83. case PARITY_ODD:
  84. uart->sci_regs->SCICCR.bit.PARITYENA = 1;
  85. uart->sci_regs->SCICCR.bit.PARITY = 0;
  86. break;
  87. case PARITY_EVEN:
  88. uart->sci_regs->SCICCR.bit.PARITYENA = 1;
  89. uart->sci_regs->SCICCR.bit.PARITY = 1;
  90. break;
  91. default:
  92. uart->sci_regs->SCICCR.bit.PARITYENA = 0;
  93. break;
  94. }
  95. EDIS;
  96. return RT_EOK;
  97. }
  98. static rt_err_t c28x_control(struct rt_serial_device *serial, int cmd, void *arg)
  99. {
  100. struct c28x_uart *uart;
  101. uart = (struct c28x_uart *)serial->parent.user_data;
  102. EALLOW;
  103. switch (cmd)
  104. {
  105. /* disable interrupt */
  106. case RT_DEVICE_CTRL_CLR_INT:
  107. /* disable interrupt */
  108. uart->sci_regs->SCICTL2.bit.TXINTENA = 0;
  109. uart->sci_regs->SCICTL2.bit.RXBKINTENA = 0;
  110. break;
  111. /* enable interrupt */
  112. case RT_DEVICE_CTRL_SET_INT:
  113. /* enable interrupt */
  114. uart->sci_regs->SCICTL2.bit.TXINTENA = 1;
  115. uart->sci_regs->SCICTL2.bit.RXBKINTENA = 1;
  116. break;
  117. }
  118. return RT_EOK;
  119. }
  120. static int c28x_putc(struct rt_serial_device *serial, char c)
  121. {
  122. SCI_write(0, &c, 1);
  123. return 1;
  124. }
  125. static int c28x_getc(struct rt_serial_device *serial)
  126. {
  127. char ch;
  128. if(SCI_read(0, &ch, 1))
  129. return ch;
  130. else
  131. return -1;
  132. }
  133. /**
  134. * Uart common interrupt process. This need add to uart ISR.
  135. *
  136. * @param serial serial device
  137. */
  138. static void uart_isr(struct rt_serial_device *serial) {
  139. struct c28x_uart *uart = (struct c28x_uart *) serial->parent.user_data;
  140. RT_ASSERT(uart != RT_NULL);
  141. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  142. SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // Clear Interrupt flag
  143. PieCtrlRegs.PIEACK.all |= 0x100; // Issue PIE ack
  144. }
  145. static const struct rt_uart_ops c28x_uart_ops =
  146. {
  147. .configure = c28x_configure,
  148. .control = c28x_control,
  149. .putc = c28x_putc,
  150. .getc = c28x_getc,
  151. };
  152. //
  153. // sciaRxFifoIsr - SCIA Receive FIFO ISR
  154. //
  155. interrupt void sciaRxFifoIsr(void)
  156. {
  157. /* enter interrupt */
  158. rt_interrupt_enter();
  159. uart_isr(&uart_obj[0].serial);
  160. /* leave interrupt */
  161. rt_interrupt_leave();
  162. }
  163. int rt_hw_sci_init(void)
  164. {
  165. EALLOW;
  166. GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;
  167. GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;
  168. GpioCtrlRegs.GPBGMUX1.bit.GPIO42 = 3;
  169. GpioCtrlRegs.GPBGMUX1.bit.GPIO43 = 3;
  170. GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 2;
  171. GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 2;
  172. GpioCtrlRegs.GPAGMUX2.bit.GPIO18 = 0;
  173. GpioCtrlRegs.GPAGMUX2.bit.GPIO19 = 0;
  174. GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2;
  175. GpioCtrlRegs.GPEMUX1.bit.GPIO139 = 2;
  176. GpioCtrlRegs.GPBGMUX2.bit.GPIO56 = 1;
  177. GpioCtrlRegs.GPEGMUX1.bit.GPIO139 = 1;
  178. CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
  179. CpuSysRegs.PCLKCR7.bit.SCI_B = 1;
  180. CpuSysRegs.PCLKCR7.bit.SCI_C = 1;
  181. PieVectTable.SCIA_RX_INT = &sciaRxFifoIsr;
  182. EDIS;
  183. //
  184. // Enable interrupts required for this example
  185. //
  186. PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
  187. PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // PIE Group 9, INT1
  188. IER |= 0x100; // Enable CPU INT
  189. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  190. rt_err_t result = 0;
  191. uart_obj[0].serial.ops = &c28x_uart_ops;
  192. uart_obj[0].serial.config = config;
  193. uart_obj[0].name = "scia";
  194. uart_obj[0].sci_regs = &SciaRegs;
  195. uart_obj[1].serial.ops = &c28x_uart_ops;
  196. uart_obj[1].serial.config = config;
  197. uart_obj[1].name = "scib";
  198. uart_obj[1].sci_regs = &ScibRegs;
  199. uart_obj[2].serial.ops = &c28x_uart_ops;
  200. uart_obj[2].serial.config = config;
  201. uart_obj[2].name = "scic";
  202. uart_obj[2].sci_regs = &ScicRegs;
  203. /* register UART device */
  204. result = rt_hw_serial_register(&uart_obj[0].serial, uart_obj[0].name,
  205. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  206. &uart_obj[0]);
  207. /* register UART device */
  208. result = rt_hw_serial_register(&uart_obj[1].serial, uart_obj[1].name,
  209. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  210. &uart_obj[1]);
  211. /* register UART device */
  212. result = rt_hw_serial_register(&uart_obj[2].serial, uart_obj[2].name,
  213. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  214. &uart_obj[2]);
  215. return result;
  216. }
  217. #endif /* RT_USING_SERIAL */