uart.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. * 2010-03-08 Bernard The first version for LPC17xx
  9. * 2010-04-10 fify Modified for M16C
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #include "iom16c62p.h"
  14. #include "bsp.h"
  15. #include "uart.h"
  16. #if defined(RT_USING_UART0) && defined(RT_USING_DEVICE)
  17. struct rt_uart_m16c
  18. {
  19. struct rt_device parent;
  20. /* buffer for reception */
  21. rt_uint8_t read_index, save_index;
  22. rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
  23. }uart_device;
  24. void u0rec_handler(void)
  25. {
  26. rt_ubase_t level;
  27. rt_uint8_t c;
  28. struct rt_uart_m16c *uart = &uart_device;
  29. while (U0C1.BIT.RI == 0)
  30. ;
  31. c = U0RB.BYTE.U0RBL;
  32. /* Receive Data Available */
  33. uart->rx_buffer[uart->save_index] = c;
  34. level = rt_hw_interrupt_disable();
  35. uart->save_index ++;
  36. if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
  37. uart->save_index = 0;
  38. rt_hw_interrupt_enable(level);
  39. /* invoke callback */
  40. if (uart->parent.rx_indicate != RT_NULL)
  41. {
  42. rt_size_t length;
  43. if (uart->read_index > uart->save_index)
  44. length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
  45. else
  46. length = uart->save_index - uart->read_index;
  47. uart->parent.rx_indicate(&uart->parent, length);
  48. }
  49. }
  50. static rt_err_t rt_uart_init (rt_device_t dev)
  51. {
  52. rt_uint32_t level;
  53. /* set UART0 bit rate generator bit rate can be calculated by:
  54. bit rate = ((BRG count source / 16)/baud rate) - 1
  55. Baud rate is based on main crystal or PLL not CPU core clock */
  56. //pclk1 = 1; /// seleck F1SIO
  57. U0BRG = (unsigned char)(((CPU_CLK_FREQ/16)/BAUD_RATE)-1); //(N+1)
  58. /* UART Transmit/Receive Control Register 2 */
  59. UCON.BYTE = 0x00;
  60. /* 00000000
  61. b0 U0IRS UART0 transmit irq cause select bit, 0 = transmit buffer empty
  62. b1 U1IRS UART1 transmit irq cause select bit, 0 = transmit buffer empty
  63. b2 U0RRM UART0 continuous receive mode enable bit, set to 0 in UART mode
  64. b3 U1RRM UART1 continuous receive mode enable bit, set to 0 in UART mode
  65. b4 CLKMD0 CLK/CLKS select bit 0, set to 0 in UART mode
  66. b5 CLKMD1 CLK/CLKS select bit 1, set to 0 in UART mode
  67. b6 RCSP Separate CTS/RTS bit,
  68. b7 Reserved, set to 0 */
  69. /* UART0 transmit/receive control register 0 */
  70. /* f1 count source, CTS/RTS disabled, CMOS output */
  71. U0C0.BYTE = 0x10;
  72. /* 00010000
  73. b1:b0 CLK01:CLK0 BRG count source select bits //01 F8SIO
  74. b2 CRS CTS/RTS function select bit
  75. b3 TXEPT Transmit register empty flag
  76. b4 CRD CTS/RTS disable bit
  77. b5 NCH Data output select bit
  78. b6 CKPOL CLK polarity select bit,set to 0 in UART mode
  79. b7 UFORM Transfer format select bit,set to 0 in UART mode */
  80. /* UART0 transmit/receive control register 1 */
  81. /* disable transmit and receive, no error output pin, data not inverted */
  82. U0C1.BYTE = 0x00;
  83. /* 00000000
  84. b0 TE Transmit enable bit
  85. b1 TI Transmit buffer empty flag
  86. b2 RE Receive enable bit
  87. b3 RI Receive complete flag
  88. b5:b4 Reserved, set to 0
  89. b6 UOLCH Data logic select bit
  90. b7 UOERE Error signal output enable bit */
  91. /* UART0 transmit/receive mode register */
  92. /* 8-bit data,asynch mode, internal clock, 1 stop bit, no parity */
  93. U0MR.BYTE = 0x05;
  94. /* 00000101
  95. b2:b0 SMD12:SMD1 Serial I/O Mode select bits
  96. b3 CKDIR Internal/External clock select bit, CKDIR
  97. b4 STPS Stop bit length select bit, STPS
  98. b5 PRY Odd/even parity select bit, PRY
  99. b6 PRYE Parity enable bit, PRYE
  100. b7 IOPOL TxD, RxD I/O polarity reverse bit */
  101. /* clear UART0 receive buffer by reading */
  102. U0TB.WORD = U0RB.WORD;
  103. /* clear UART0 transmit buffer */
  104. U0TB.WORD = 0;
  105. /* disable irqs before setting irq registers */
  106. level = rt_hw_interrupt_disable();
  107. /* Enable UART0 receive interrupt, priority level 4 */
  108. S0RIC.BYTE = 0x04;
  109. /* Enable all interrupts */
  110. rt_hw_interrupt_enable(level);
  111. /* UART0 transmit/receive control register 1 */
  112. /* enable transmit and receive */
  113. U0C1.BYTE = 0x05;
  114. /* 00000101 enable transmit and receive
  115. b0 TE Transmit enable bit
  116. b1 TI Transmit buffer empty flag
  117. b2 RE Receive enable bit
  118. b3 RI Receive complete flag
  119. b5:b4 Reserved, set to 0
  120. b6 UOLCH Data logic select bit
  121. b7 UOERE Error signal output enable bit */
  122. return RT_EOK;
  123. }
  124. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  125. {
  126. RT_ASSERT(dev != RT_NULL);
  127. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  128. {
  129. /* Enable the UART Interrupt */
  130. }
  131. return RT_EOK;
  132. }
  133. static rt_err_t rt_uart_close(rt_device_t dev)
  134. {
  135. RT_ASSERT(dev != RT_NULL);
  136. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  137. {
  138. /* Disable the UART Interrupt */
  139. }
  140. return RT_EOK;
  141. }
  142. static rt_ssize_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  143. {
  144. rt_uint8_t *ptr;
  145. struct rt_uart_m16c *uart = (struct rt_uart_m16c *)dev;
  146. RT_ASSERT(uart != RT_NULL);
  147. /* point to buffer */
  148. ptr = (rt_uint8_t *)buffer;
  149. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  150. {
  151. while (size)
  152. {
  153. /* interrupt receive */
  154. rt_base_t level;
  155. /* disable interrupt */
  156. level = rt_hw_interrupt_disable();
  157. if (uart->read_index != uart->save_index)
  158. {
  159. *ptr = uart->rx_buffer[uart->read_index];
  160. uart->read_index ++;
  161. if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
  162. uart->read_index = 0;
  163. }
  164. else
  165. {
  166. /* no data in rx buffer */
  167. /* enable interrupt */
  168. rt_hw_interrupt_enable(level);
  169. break;
  170. }
  171. /* enable interrupt */
  172. rt_hw_interrupt_enable(level);
  173. ptr ++;
  174. size --;
  175. }
  176. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  177. }
  178. return 0;
  179. }
  180. static rt_ssize_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  181. {
  182. char *ptr;
  183. ptr = (char *)buffer;
  184. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  185. {
  186. /* stream mode */
  187. while (size)
  188. {
  189. if (*ptr == '\n')
  190. {
  191. while (U0C1.BIT.TI == 0)
  192. ;
  193. U0TB.BYTE.U0TBL = '\r';
  194. }
  195. /* THRE status, contain valid data */
  196. while (U0C1.BIT.TI == 0)
  197. ;
  198. U0TB.BYTE.U0TBL = *ptr;
  199. ptr ++;
  200. size --;
  201. }
  202. }
  203. else
  204. {
  205. while (size != 0)
  206. {
  207. /* THRE status, contain valid data */
  208. while (U0C1.BIT.TI == 0)
  209. ;
  210. U0TB.BYTE.U0TBL = *ptr;
  211. ptr ++;
  212. size --;
  213. }
  214. }
  215. return (rt_size_t)ptr - (rt_size_t)buffer;
  216. }
  217. void rt_hw_uart_init(void)
  218. {
  219. struct rt_uart_m16c *uart;
  220. /* get uart device */
  221. uart = &uart_device;
  222. /* device initialization */
  223. uart->parent.type = RT_Device_Class_Char;
  224. rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
  225. uart->read_index = uart->save_index = 0;
  226. /* device interface */
  227. uart->parent.init = rt_uart_init;
  228. uart->parent.open = rt_uart_open;
  229. uart->parent.close = rt_uart_close;
  230. uart->parent.read = rt_uart_read;
  231. uart->parent.write = rt_uart_write;
  232. uart->parent.control = RT_NULL;
  233. uart->parent.user_data = RT_NULL;
  234. rt_device_register(&uart->parent,
  235. "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
  236. }
  237. #endif /* end of UART */
  238. /*@}*/