uart.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #include <rtthread.h>
  2. #include "uart.h"
  3. #include "cycfg_peripherals.h"
  4. /**
  5. * @addtogroup
  6. */
  7. /*@{*/
  8. /* RT-Thread Device Interface */
  9. /**
  10. * This function initializes uart
  11. */
  12. static rt_err_t rt_uart_init (rt_device_t dev)
  13. {
  14. struct uart_device* uart = (struct uart_device*) dev->user_data;
  15. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  16. {
  17. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  18. {
  19. rt_memset(uart->int_rx->rx_buffer, 0,
  20. sizeof(uart->int_rx->rx_buffer));
  21. uart->int_rx->read_index = uart->int_rx->save_index = 0;
  22. }
  23. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  24. {
  25. rt_memset(uart->int_tx->tx_buffer, 0,
  26. sizeof(uart->int_tx->tx_buffer));
  27. uart->int_tx->write_index = uart->int_tx->save_index = 0;
  28. }
  29. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  30. }
  31. return RT_EOK;
  32. }
  33. /* save a char to uart buffer */
  34. static void rt_uart_savechar(struct uart_device* uart, char ch)
  35. {
  36. rt_base_t level;
  37. /* disable interrupt */
  38. level = rt_hw_interrupt_disable();
  39. uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
  40. uart->int_rx->save_index ++;
  41. if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
  42. uart->int_rx->save_index = 0;
  43. /* if the next position is read index, discard this 'read char' */
  44. if (uart->int_rx->save_index == uart->int_rx->read_index)
  45. {
  46. uart->int_rx->read_index ++;
  47. if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
  48. uart->int_rx->read_index = 0;
  49. }
  50. /* enable interrupt */
  51. rt_hw_interrupt_enable(level);
  52. }
  53. static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
  54. {
  55. struct uart_device* uart;
  56. oflag = oflag;
  57. RT_ASSERT(dev != RT_NULL);
  58. uart = (struct uart_device*) dev->user_data;
  59. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  60. {
  61. /* enable interrupt */
  62. UART_ENABLE_IRQ(uart->rx_irq);
  63. }
  64. return RT_EOK;
  65. }
  66. static rt_err_t rt_uart_close(rt_device_t dev)
  67. {
  68. struct uart_device* uart;
  69. RT_ASSERT(dev != RT_NULL);
  70. uart = (struct uart_device*) dev->user_data;
  71. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  72. {
  73. /* disable interrupt */
  74. UART_DISABLE_IRQ(uart->rx_irq);
  75. }
  76. return RT_EOK;
  77. }
  78. static rt_size_t rt_uart_read (rt_device_t dev, rt_off_t pos, void* buffer,
  79. rt_size_t size)
  80. {
  81. rt_uint8_t* ptr;
  82. rt_err_t err_code;
  83. struct uart_device* uart;
  84. pos = pos;
  85. ptr = buffer;
  86. err_code = RT_EOK;
  87. uart = (struct uart_device*)dev->user_data;
  88. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  89. {
  90. rt_base_t level;
  91. /* interrupt mode Rx */
  92. while (size)
  93. {
  94. if (uart->int_rx->read_index != uart->int_rx->save_index)
  95. {
  96. *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
  97. size --;
  98. /* disable interrupt */
  99. level = rt_hw_interrupt_disable();
  100. uart->int_rx->read_index ++;
  101. if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
  102. uart->int_rx->read_index = 0;
  103. /* enable interrupt */
  104. rt_hw_interrupt_enable(level);
  105. }
  106. else
  107. {
  108. /* set error code */
  109. err_code = -RT_EEMPTY;
  110. break;
  111. }
  112. }
  113. }
  114. else
  115. {
  116. /* polling mode */
  117. while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
  118. {
  119. while (0UL != Cy_SCB_UART_GetNumInRxFifo(uart->scb_device))
  120. {
  121. *ptr = Cy_SCB_UART_Get(uart->scb_device);
  122. ptr ++;
  123. }
  124. }
  125. }
  126. /* set error code */
  127. rt_set_errno(err_code);
  128. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  129. }
  130. static rt_size_t rt_uart_write (rt_device_t dev, rt_off_t pos,
  131. const void* buffer, rt_size_t size)
  132. {
  133. rt_uint8_t* ptr;
  134. rt_err_t err_code;
  135. struct uart_device* uart;
  136. pos = pos;
  137. err_code = RT_EOK;
  138. ptr = (rt_uint8_t*)buffer;
  139. uart = (struct uart_device*)dev->user_data;
  140. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  141. {
  142. /* interrupt mode Tx */
  143. while (uart->int_tx->save_index != uart->int_tx->write_index)
  144. {
  145. /* save on tx buffer */
  146. uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
  147. -- size;
  148. /* move to next position */
  149. uart->int_tx->save_index ++;
  150. /* wrap save index */
  151. if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
  152. uart->int_tx->save_index = 0;
  153. }
  154. /* set error code */
  155. if (size > 0)
  156. err_code = -RT_EFULL;
  157. }
  158. else
  159. {
  160. /* polling mode */
  161. while (size)
  162. {
  163. /*
  164. * to be polite with serial console add a line feed
  165. * to the carriage return character
  166. */
  167. if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
  168. {
  169. while(0 == Cy_SCB_UART_Put(uart->scb_device, '\r'));
  170. }
  171. while(0 == Cy_SCB_UART_Put(uart->scb_device, (*ptr & 0x1FF)));
  172. ++ptr;
  173. --size;
  174. }
  175. }
  176. /* set error code */
  177. rt_set_errno(err_code);
  178. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  179. }
  180. static rt_err_t rt_uart_control (rt_device_t dev, int cmd, void *args)
  181. {
  182. RT_ASSERT(dev != RT_NULL);
  183. args = args;
  184. switch (cmd)
  185. {
  186. case RT_DEVICE_CTRL_SUSPEND:
  187. /* suspend device */
  188. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  189. break;
  190. case RT_DEVICE_CTRL_RESUME:
  191. /* resume device */
  192. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  193. break;
  194. }
  195. return RT_EOK;
  196. }
  197. /*
  198. * serial register
  199. */
  200. rt_err_t rt_hw_uart_register(rt_device_t device, const char* name,
  201. rt_uint32_t flag, struct uart_device *serial)
  202. {
  203. RT_ASSERT(device != RT_NULL);
  204. device->type = RT_Device_Class_Char;
  205. device->rx_indicate = RT_NULL;
  206. device->tx_complete = RT_NULL;
  207. device->init = rt_uart_init;
  208. device->open = rt_uart_open;
  209. device->close = rt_uart_close;
  210. device->read = rt_uart_read;
  211. device->write = rt_uart_write;
  212. device->control = rt_uart_control;
  213. device->user_data = serial;
  214. /* register a character device */
  215. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  216. }
  217. /* ISR for uart interrupt */
  218. void rt_hw_uart_isr(rt_device_t device)
  219. {
  220. struct uart_device* uart = (struct uart_device*) device->user_data;
  221. /* interrupt mode receive */
  222. RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
  223. /* Check for "RX fifo not empty interrupt" */
  224. if((uart->scb_device->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0)
  225. {
  226. /* Clear UART "RX fifo not empty interrupt" */
  227. uart->scb_device->INTR_RX = uart->scb_device->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;
  228. /* Get the character from terminal */
  229. rt_uart_savechar(uart, Cy_SCB_UART_Get(uart->scb_device));
  230. }
  231. /* invoke callback */
  232. if (device->rx_indicate != RT_NULL)
  233. {
  234. rt_size_t rx_length;
  235. /* get rx length */
  236. rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
  237. UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
  238. uart->int_rx->save_index - uart->int_rx->read_index;
  239. device->rx_indicate(device, rx_length);
  240. }
  241. }
  242. #ifdef RT_USING_UART0
  243. /* UART0 device driver structure */
  244. #define UART0_SCB_IRQ__INTC_NUMBER 46u
  245. cy_stc_scb_uart_context_t UART0_context;
  246. const cy_stc_sysint_t UART0_SCB_IRQ_cfg =
  247. {
  248. .intrSrc = scb_5_interrupt_IRQn,
  249. .intrPriority = 3u,
  250. };
  251. /* UART0 device driver structure */
  252. struct uart_int_rx uart0_int_rx;
  253. struct uart_device uart0 =
  254. {
  255. UART0_HW,
  256. &UART0_config,
  257. &UART0_context,
  258. &UART0_SCB_IRQ_cfg,
  259. (IRQn_Type)UART0_SCB_IRQ__INTC_NUMBER,
  260. (IRQn_Type)UART0_SCB_IRQ__INTC_NUMBER,
  261. &uart0_int_rx,
  262. RT_NULL
  263. };
  264. struct rt_device uart0_device;
  265. /* UART0 Interrupt Hanlder */
  266. void uart0_isr_callback(void)
  267. {
  268. /* enter interrupt */
  269. rt_interrupt_enter();
  270. rt_hw_uart_isr(&uart0_device);
  271. /* leave interrupt */
  272. rt_interrupt_leave();
  273. }
  274. #endif
  275. void rt_hw_uart_init(void)
  276. {
  277. /* Start UART operation. */
  278. if(Cy_SCB_UART_Init(uart0.scb_device, uart0.uart_config, uart0.uart_context) != CY_SCB_UART_SUCCESS)
  279. {
  280. rt_assert_handler("UART0 init", __FUNCTION__, __LINE__);
  281. }
  282. Cy_SCB_UART_Enable(uart0.scb_device);
  283. /* Unmasking only the RX fifo not empty interrupt bit */
  284. uart0.scb_device->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk;
  285. /* Interrupt Settings for UART */
  286. Cy_SysInt_Init(uart0.uart_int, uart0_isr_callback);
  287. /* Enable the interrupt */
  288. NVIC_EnableIRQ(uart0.uart_int->intrSrc);
  289. /* register UART0 device */
  290. rt_hw_uart_register(&uart0_device,
  291. "uart0",
  292. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
  293. &uart0);
  294. }
  295. /*@}*/