1
0

serial.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * File : serial.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009, RT-Thread Development 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. * 2009-02-05 Bernard first version
  13. * 2009-10-25 Bernard fix rt_serial_read bug when there is no data
  14. * in the buffer.
  15. * 2010-03-29 Bernard cleanup code.
  16. */
  17. #include "serial.h"
  18. #include <stm32f10x_dma.h>
  19. #include <stm32f10x_usart.h>
  20. static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
  21. rt_uint32_t address, rt_uint32_t size);
  22. /**
  23. * @addtogroup STM32
  24. */
  25. /*@{*/
  26. /* RT-Thread Device Interface */
  27. static rt_err_t rt_serial_init (rt_device_t dev)
  28. {
  29. struct stm32_serial_device* uart = (struct stm32_serial_device*) dev->user_data;
  30. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  31. {
  32. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  33. {
  34. rt_memset(uart->int_rx->rx_buffer, 0,
  35. sizeof(uart->int_rx->rx_buffer));
  36. uart->int_rx->read_index = 0;
  37. uart->int_rx->save_index = 0;
  38. }
  39. if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  40. {
  41. RT_ASSERT(uart->dma_tx->dma_channel != RT_NULL);
  42. uart->dma_tx->list_head = uart->dma_tx->list_tail = RT_NULL;
  43. /* init data node memory pool */
  44. rt_mp_init(&(uart->dma_tx->data_node_mp), "dn",
  45. uart->dma_tx->data_node_mem_pool,
  46. sizeof(uart->dma_tx->data_node_mem_pool),
  47. sizeof(struct stm32_serial_data_node));
  48. }
  49. /* Enable USART */
  50. USART_Cmd(uart->uart_device, ENABLE);
  51. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  52. }
  53. return RT_EOK;
  54. }
  55. static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
  56. {
  57. return RT_EOK;
  58. }
  59. static rt_err_t rt_serial_close(rt_device_t dev)
  60. {
  61. return RT_EOK;
  62. }
  63. static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  64. {
  65. rt_uint8_t* ptr;
  66. rt_err_t err_code;
  67. struct stm32_serial_device* uart;
  68. ptr = buffer;
  69. err_code = RT_EOK;
  70. uart = (struct stm32_serial_device*)dev->user_data;
  71. if (dev->flag & RT_DEVICE_FLAG_INT_RX)
  72. {
  73. /* interrupt mode Rx */
  74. while (size)
  75. {
  76. rt_base_t level;
  77. /* disable interrupt */
  78. level = rt_hw_interrupt_disable();
  79. if (uart->int_rx->read_index != uart->int_rx->save_index)
  80. {
  81. /* read a character */
  82. *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
  83. size--;
  84. /* move to next position */
  85. uart->int_rx->read_index ++;
  86. if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
  87. uart->int_rx->read_index = 0;
  88. }
  89. else
  90. {
  91. /* set error code */
  92. err_code = -RT_EEMPTY;
  93. /* enable interrupt */
  94. rt_hw_interrupt_enable(level);
  95. break;
  96. }
  97. /* enable interrupt */
  98. rt_hw_interrupt_enable(level);
  99. }
  100. }
  101. else
  102. {
  103. /* polling mode */
  104. while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
  105. {
  106. while (uart->uart_device->SR & USART_FLAG_RXNE)
  107. {
  108. *ptr = uart->uart_device->DR & 0xff;
  109. ptr ++;
  110. }
  111. }
  112. }
  113. /* set error code */
  114. rt_set_errno(err_code);
  115. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  116. }
  117. static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
  118. rt_uint32_t address, rt_uint32_t size)
  119. {
  120. RT_ASSERT(dma_channel != RT_NULL);
  121. /* disable DMA */
  122. DMA_Cmd(dma_channel, DISABLE);
  123. /* set buffer address */
  124. dma_channel->CMAR = address;
  125. /* set size */
  126. dma_channel->CNDTR = size;
  127. /* enable DMA */
  128. DMA_Cmd(dma_channel, ENABLE);
  129. }
  130. static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  131. {
  132. rt_uint8_t* ptr;
  133. rt_err_t err_code;
  134. struct stm32_serial_device* uart;
  135. err_code = RT_EOK;
  136. ptr = (rt_uint8_t*)buffer;
  137. uart = (struct stm32_serial_device*)dev->user_data;
  138. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  139. {
  140. /* interrupt mode Tx, does not support */
  141. RT_ASSERT(0);
  142. }
  143. else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  144. {
  145. /* DMA mode Tx */
  146. /* allocate a data node */
  147. struct stm32_serial_data_node* data_node = (struct stm32_serial_data_node*)
  148. rt_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER);
  149. if (data_node == RT_NULL)
  150. {
  151. /* set error code */
  152. err_code = -RT_ENOMEM;
  153. }
  154. else
  155. {
  156. rt_uint32_t level;
  157. /* fill data node */
  158. data_node->data_ptr = ptr;
  159. data_node->data_size = size;
  160. /* insert to data link */
  161. data_node->next = RT_NULL;
  162. /* disable interrupt */
  163. level = rt_hw_interrupt_disable();
  164. data_node->prev = uart->dma_tx->list_tail;
  165. if (uart->dma_tx->list_tail != RT_NULL)
  166. uart->dma_tx->list_tail->next = data_node;
  167. uart->dma_tx->list_tail = data_node;
  168. if (uart->dma_tx->list_head == RT_NULL)
  169. {
  170. /* start DMA to transmit data */
  171. uart->dma_tx->list_head = data_node;
  172. /* Enable DMA Channel */
  173. rt_serial_enable_dma(uart->dma_tx->dma_channel,
  174. (rt_uint32_t)uart->dma_tx->list_head->data_ptr,
  175. uart->dma_tx->list_head->data_size);
  176. }
  177. /* enable interrupt */
  178. rt_hw_interrupt_enable(level);
  179. }
  180. }
  181. else
  182. {
  183. /* polling mode */
  184. if (dev->flag & RT_DEVICE_FLAG_STREAM)
  185. {
  186. /* stream mode */
  187. while (size)
  188. {
  189. if (*ptr == '\n')
  190. {
  191. while (!(uart->uart_device->SR & USART_FLAG_TXE));
  192. uart->uart_device->DR = '\r';
  193. }
  194. while (!(uart->uart_device->SR & USART_FLAG_TXE));
  195. uart->uart_device->DR = (*ptr & 0x1FF);
  196. ++ptr; --size;
  197. }
  198. }
  199. else
  200. {
  201. /* write data directly */
  202. while (size)
  203. {
  204. while (!(uart->uart_device->SR & USART_FLAG_TXE));
  205. uart->uart_device->DR = (*ptr & 0x1FF);
  206. ++ptr; --size;
  207. }
  208. }
  209. }
  210. /* set error code */
  211. rt_set_errno(err_code);
  212. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  213. }
  214. static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
  215. {
  216. struct stm32_serial_device* uart;
  217. RT_ASSERT(dev != RT_NULL);
  218. uart = (struct stm32_serial_device*)dev->user_data;
  219. switch (cmd)
  220. {
  221. case RT_DEVICE_CTRL_SUSPEND:
  222. /* suspend device */
  223. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  224. USART_Cmd(uart->uart_device, DISABLE);
  225. break;
  226. case RT_DEVICE_CTRL_RESUME:
  227. /* resume device */
  228. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  229. USART_Cmd(uart->uart_device, ENABLE);
  230. break;
  231. }
  232. return RT_EOK;
  233. }
  234. /*
  235. * serial register for STM32
  236. * support STM32F103VB and STM32F103ZE
  237. */
  238. rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct stm32_serial_device *serial)
  239. {
  240. RT_ASSERT(device != RT_NULL);
  241. if ((flag & RT_DEVICE_FLAG_DMA_RX) ||
  242. (flag & RT_DEVICE_FLAG_INT_TX))
  243. {
  244. RT_ASSERT(0);
  245. }
  246. device->type = RT_Device_Class_Char;
  247. device->rx_indicate = RT_NULL;
  248. device->tx_complete = RT_NULL;
  249. device->init = rt_serial_init;
  250. device->open = rt_serial_open;
  251. device->close = rt_serial_close;
  252. device->read = rt_serial_read;
  253. device->write = rt_serial_write;
  254. device->control = rt_serial_control;
  255. device->user_data = serial;
  256. /* register a character device */
  257. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  258. }
  259. /* ISR for serial interrupt */
  260. void rt_hw_serial_isr(rt_device_t device)
  261. {
  262. struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data;
  263. if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
  264. {
  265. /* interrupt mode receive */
  266. RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
  267. /* save on rx buffer */
  268. while (uart->uart_device->SR & USART_FLAG_RXNE)
  269. {
  270. rt_base_t level;
  271. /* disable interrupt */
  272. level = rt_hw_interrupt_disable();
  273. /* save character */
  274. uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->DR & 0xff;
  275. uart->int_rx->save_index ++;
  276. if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
  277. uart->int_rx->save_index = 0;
  278. /* if the next position is read index, discard this 'read char' */
  279. if (uart->int_rx->save_index == uart->int_rx->read_index)
  280. {
  281. uart->int_rx->read_index ++;
  282. if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
  283. uart->int_rx->read_index = 0;
  284. }
  285. /* enable interrupt */
  286. rt_hw_interrupt_enable(level);
  287. }
  288. /* clear interrupt */
  289. USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
  290. /* invoke callback */
  291. if (device->rx_indicate != RT_NULL)
  292. {
  293. rt_size_t rx_length;
  294. /* get rx length */
  295. rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
  296. UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
  297. uart->int_rx->save_index - uart->int_rx->read_index;
  298. device->rx_indicate(device, rx_length);
  299. }
  300. }
  301. if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
  302. {
  303. /* clear interrupt */
  304. USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
  305. }
  306. }
  307. /*
  308. * ISR for DMA mode Tx
  309. */
  310. void rt_hw_serial_dma_tx_isr(rt_device_t device)
  311. {
  312. rt_uint32_t level;
  313. struct stm32_serial_data_node* data_node;
  314. struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data;
  315. /* DMA mode receive */
  316. RT_ASSERT(device->flag & RT_DEVICE_FLAG_DMA_TX);
  317. /* get the first data node */
  318. data_node = uart->dma_tx->list_head;
  319. RT_ASSERT(data_node != RT_NULL);
  320. /* invoke call to notify tx complete */
  321. if (device->tx_complete != RT_NULL)
  322. device->tx_complete(device, data_node->data_ptr);
  323. /* disable interrupt */
  324. level = rt_hw_interrupt_disable();
  325. /* remove list head */
  326. uart->dma_tx->list_head = data_node->next;
  327. if (uart->dma_tx->list_head == RT_NULL) /* data link empty */
  328. uart->dma_tx->list_tail = RT_NULL;
  329. /* enable interrupt */
  330. rt_hw_interrupt_enable(level);
  331. /* release data node memory */
  332. rt_mp_free(data_node);
  333. if (uart->dma_tx->list_head != RT_NULL)
  334. {
  335. /* transmit next data node */
  336. rt_serial_enable_dma(uart->dma_tx->dma_channel,
  337. (rt_uint32_t)uart->dma_tx->list_head->data_ptr,
  338. uart->dma_tx->list_head->data_size);
  339. }
  340. else
  341. {
  342. /* no data to be transmitted, disable DMA */
  343. DMA_Cmd(uart->dma_tx->dma_channel, DISABLE);
  344. }
  345. }
  346. /*@}*/