serial.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  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. * 2006-03-13 bernard first version
  9. * 2012-05-15 lgnq modified according bernard's implementation.
  10. * 2012-05-28 bernard code cleanup
  11. * 2012-11-23 bernard fix compiler warning.
  12. * 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define
  13. * the size of ring buffer.
  14. * 2014-07-10 bernard rewrite serial framework
  15. * 2014-12-31 bernard use open_flag for poll_tx stream mode.
  16. * 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG
  17. * in open function.
  18. * 2015-11-10 bernard fix the poll rx issue when there is no data.
  19. * 2016-05-10 armink add fifo mode to DMA rx when serial->config.bufsz != 0.
  20. * 2017-01-19 aubr.cool prevent change serial rx bufsz when serial is opened.
  21. * 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
  22. * 2017-11-15 JasonJia fix poll rx issue when data is full.
  23. * add TCFLSH and FIONREAD support.
  24. * 2018-12-08 Ernest Chen add DMA choice
  25. * 2020-09-14 WillianChan add a line feed to the carriage return character
  26. * when using interrupt tx
  27. */
  28. #include <rthw.h>
  29. #include <rtthread.h>
  30. #include <rtdevice.h>
  31. #define DBG_TAG "UART"
  32. #define DBG_LVL DBG_INFO
  33. #include <rtdbg.h>
  34. #ifdef RT_USING_POSIX
  35. #include <dfs_posix.h>
  36. #include <dfs_poll.h>
  37. /* it's possible the 'getc/putc' is defined by stdio.h in gcc/newlib. */
  38. #ifdef getc
  39. #undef getc
  40. #endif
  41. #ifdef putc
  42. #undef putc
  43. #endif
  44. static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
  45. {
  46. rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
  47. return RT_EOK;
  48. }
  49. /* fops for serial */
  50. static int serial_fops_open(struct dfs_fd *fd)
  51. {
  52. rt_err_t ret = 0;
  53. rt_uint16_t flags = 0;
  54. rt_device_t device;
  55. device = (rt_device_t)fd->fnode->data;
  56. RT_ASSERT(device != RT_NULL);
  57. switch (fd->flags & O_ACCMODE)
  58. {
  59. case O_RDONLY:
  60. LOG_D("fops open: O_RDONLY!");
  61. flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY;
  62. break;
  63. case O_WRONLY:
  64. LOG_D("fops open: O_WRONLY!");
  65. flags = RT_DEVICE_FLAG_WRONLY;
  66. break;
  67. case O_RDWR:
  68. LOG_D("fops open: O_RDWR!");
  69. flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR;
  70. break;
  71. default:
  72. LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
  73. break;
  74. }
  75. if ((fd->flags & O_ACCMODE) != O_WRONLY)
  76. {
  77. rt_device_set_rx_indicate(device, serial_fops_rx_ind);
  78. }
  79. ret = rt_device_open(device, flags);
  80. if (ret == RT_EOK)
  81. {
  82. return 0;
  83. }
  84. return ret;
  85. }
  86. static int serial_fops_close(struct dfs_fd *fd)
  87. {
  88. rt_device_t device;
  89. device = (rt_device_t)fd->fnode->data;
  90. rt_device_set_rx_indicate(device, RT_NULL);
  91. rt_device_close(device);
  92. return 0;
  93. }
  94. static int serial_fops_ioctl(struct dfs_fd *fd, int cmd, void *args)
  95. {
  96. rt_device_t device;
  97. device = (rt_device_t)fd->fnode->data;
  98. switch (cmd)
  99. {
  100. case FIONREAD:
  101. break;
  102. case FIONWRITE:
  103. break;
  104. }
  105. return rt_device_control(device, cmd, args);
  106. }
  107. static int serial_fops_read(struct dfs_fd *fd, void *buf, size_t count)
  108. {
  109. int size = 0;
  110. rt_device_t device;
  111. int wait_ret;
  112. device = (rt_device_t)fd->fnode->data;
  113. do
  114. {
  115. size = rt_device_read(device, -1, buf, count);
  116. if (size <= 0)
  117. {
  118. if (fd->flags & O_NONBLOCK)
  119. {
  120. break;
  121. }
  122. wait_ret = rt_wqueue_wait_interruptible(&(device->wait_queue), 0, RT_WAITING_FOREVER);
  123. if (wait_ret != RT_EOK)
  124. {
  125. break;
  126. }
  127. }
  128. }while (size <= 0);
  129. if (size < 0)
  130. {
  131. size = 0;
  132. }
  133. return size;
  134. }
  135. static int serial_fops_write(struct dfs_fd *fd, const void *buf, size_t count)
  136. {
  137. rt_device_t device;
  138. device = (rt_device_t)fd->fnode->data;
  139. return rt_device_write(device, -1, buf, count);
  140. }
  141. static int serial_fops_poll(struct dfs_fd *fd, struct rt_pollreq *req)
  142. {
  143. int mask = 0;
  144. int flags = 0;
  145. rt_device_t device;
  146. struct rt_serial_device *serial;
  147. device = (rt_device_t)fd->fnode->data;
  148. RT_ASSERT(device != RT_NULL);
  149. serial = (struct rt_serial_device *)device;
  150. /* only support POLLIN */
  151. flags = fd->flags & O_ACCMODE;
  152. if (flags == O_RDONLY || flags == O_RDWR)
  153. {
  154. rt_base_t level;
  155. struct rt_serial_rx_fifo* rx_fifo;
  156. rt_poll_add(&(device->wait_queue), req);
  157. rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
  158. level = rt_hw_interrupt_disable();
  159. if ((rx_fifo->get_index != rx_fifo->put_index) || (rx_fifo->get_index == rx_fifo->put_index && rx_fifo->is_full == RT_TRUE))
  160. mask |= POLLIN;
  161. rt_hw_interrupt_enable(level);
  162. }
  163. return mask;
  164. }
  165. const static struct dfs_file_ops _serial_fops =
  166. {
  167. serial_fops_open,
  168. serial_fops_close,
  169. serial_fops_ioctl,
  170. serial_fops_read,
  171. serial_fops_write,
  172. RT_NULL, /* flush */
  173. RT_NULL, /* lseek */
  174. RT_NULL, /* getdents */
  175. serial_fops_poll,
  176. };
  177. #endif
  178. /*
  179. * Serial poll routines
  180. */
  181. rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
  182. {
  183. int ch;
  184. int size;
  185. RT_ASSERT(serial != RT_NULL);
  186. size = length;
  187. while (length)
  188. {
  189. ch = serial->ops->getc(serial);
  190. if (ch == -1) break;
  191. *data = ch;
  192. data ++; length --;
  193. if (ch == '\n') break;
  194. }
  195. return size - length;
  196. }
  197. rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
  198. {
  199. int size;
  200. RT_ASSERT(serial != RT_NULL);
  201. size = length;
  202. while (length)
  203. {
  204. /*
  205. * to be polite with serial console add a line feed
  206. * to the carriage return character
  207. */
  208. if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
  209. {
  210. serial->ops->putc(serial, '\r');
  211. }
  212. serial->ops->putc(serial, *data);
  213. ++ data;
  214. -- length;
  215. }
  216. return size - length;
  217. }
  218. /*
  219. * Serial interrupt routines
  220. */
  221. rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
  222. {
  223. int size;
  224. struct rt_serial_rx_fifo* rx_fifo;
  225. RT_ASSERT(serial != RT_NULL);
  226. size = length;
  227. rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
  228. RT_ASSERT(rx_fifo != RT_NULL);
  229. /* read from software FIFO */
  230. while (length)
  231. {
  232. int ch;
  233. rt_base_t level;
  234. /* disable interrupt */
  235. level = rt_hw_interrupt_disable();
  236. /* there's no data: */
  237. if ((rx_fifo->get_index == rx_fifo->put_index) && (rx_fifo->is_full == RT_FALSE))
  238. {
  239. /* no data, enable interrupt and break out */
  240. rt_hw_interrupt_enable(level);
  241. break;
  242. }
  243. /* otherwise there's the data: */
  244. ch = rx_fifo->buffer[rx_fifo->get_index];
  245. rx_fifo->get_index += 1;
  246. if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
  247. if (rx_fifo->is_full == RT_TRUE)
  248. {
  249. rx_fifo->is_full = RT_FALSE;
  250. }
  251. /* enable interrupt */
  252. rt_hw_interrupt_enable(level);
  253. *data = ch & 0xff;
  254. data ++; length --;
  255. }
  256. return size - length;
  257. }
  258. rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
  259. {
  260. int size;
  261. struct rt_serial_tx_fifo *tx;
  262. RT_ASSERT(serial != RT_NULL);
  263. size = length;
  264. tx = (struct rt_serial_tx_fifo*) serial->serial_tx;
  265. RT_ASSERT(tx != RT_NULL);
  266. while (length)
  267. {
  268. /*
  269. * to be polite with serial console add a line feed
  270. * to the carriage return character
  271. */
  272. if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
  273. {
  274. if (serial->ops->putc(serial, '\r') == -1)
  275. {
  276. rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
  277. continue;
  278. }
  279. }
  280. if (serial->ops->putc(serial, *(char*)data) == -1)
  281. {
  282. rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
  283. continue;
  284. }
  285. data ++; length --;
  286. }
  287. return size - length;
  288. }
  289. static void _serial_check_buffer_size(void)
  290. {
  291. static rt_bool_t already_output = RT_FALSE;
  292. if (already_output == RT_FALSE)
  293. {
  294. #if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG)
  295. LOG_W("Warning: There is no enough buffer for saving data,"
  296. " please increase the RT_SERIAL_RB_BUFSZ option.");
  297. #endif
  298. already_output = RT_TRUE;
  299. }
  300. }
  301. #if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA)
  302. static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
  303. {
  304. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
  305. RT_ASSERT(rx_fifo != RT_NULL);
  306. if (rx_fifo->put_index == rx_fifo->get_index)
  307. {
  308. return (rx_fifo->is_full == RT_FALSE ? 0 : serial->config.bufsz);
  309. }
  310. else
  311. {
  312. if (rx_fifo->put_index > rx_fifo->get_index)
  313. {
  314. return rx_fifo->put_index - rx_fifo->get_index;
  315. }
  316. else
  317. {
  318. return serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index);
  319. }
  320. }
  321. }
  322. #endif /* RT_USING_POSIX || RT_SERIAL_USING_DMA */
  323. #ifdef RT_SERIAL_USING_DMA
  324. /**
  325. * Calculate DMA received data length.
  326. *
  327. * @param serial serial device
  328. *
  329. * @return length
  330. */
  331. static rt_size_t rt_dma_calc_recved_len(struct rt_serial_device *serial)
  332. {
  333. return _serial_fifo_calc_recved_len(serial);
  334. }
  335. /**
  336. * Read data finish by DMA mode then update the get index for receive fifo.
  337. *
  338. * @param serial serial device
  339. * @param len get data length for this operate
  340. */
  341. static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_size_t len)
  342. {
  343. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
  344. RT_ASSERT(rx_fifo != RT_NULL);
  345. RT_ASSERT(len <= rt_dma_calc_recved_len(serial));
  346. if (rx_fifo->is_full && len != 0) rx_fifo->is_full = RT_FALSE;
  347. rx_fifo->get_index += len;
  348. if (rx_fifo->get_index >= serial->config.bufsz)
  349. {
  350. rx_fifo->get_index %= serial->config.bufsz;
  351. }
  352. }
  353. /**
  354. * DMA received finish then update put index for receive fifo.
  355. *
  356. * @param serial serial device
  357. * @param len received length for this transmit
  358. */
  359. static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_size_t len)
  360. {
  361. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  362. RT_ASSERT(rx_fifo != RT_NULL);
  363. if (rx_fifo->get_index <= rx_fifo->put_index)
  364. {
  365. rx_fifo->put_index += len;
  366. /* beyond the fifo end */
  367. if (rx_fifo->put_index >= serial->config.bufsz)
  368. {
  369. rx_fifo->put_index %= serial->config.bufsz;
  370. /* force overwrite get index */
  371. if (rx_fifo->put_index >= rx_fifo->get_index)
  372. {
  373. rx_fifo->is_full = RT_TRUE;
  374. }
  375. }
  376. }
  377. else
  378. {
  379. rx_fifo->put_index += len;
  380. if (rx_fifo->put_index >= rx_fifo->get_index)
  381. {
  382. /* beyond the fifo end */
  383. if (rx_fifo->put_index >= serial->config.bufsz)
  384. {
  385. rx_fifo->put_index %= serial->config.bufsz;
  386. }
  387. /* force overwrite get index */
  388. rx_fifo->is_full = RT_TRUE;
  389. }
  390. }
  391. if(rx_fifo->is_full == RT_TRUE)
  392. {
  393. _serial_check_buffer_size();
  394. rx_fifo->get_index = rx_fifo->put_index;
  395. }
  396. }
  397. /*
  398. * Serial DMA routines
  399. */
  400. rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
  401. {
  402. rt_base_t level;
  403. RT_ASSERT((serial != RT_NULL) && (data != RT_NULL));
  404. level = rt_hw_interrupt_disable();
  405. if (serial->config.bufsz == 0)
  406. {
  407. int result = RT_EOK;
  408. struct rt_serial_rx_dma *rx_dma;
  409. rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
  410. RT_ASSERT(rx_dma != RT_NULL);
  411. if (rx_dma->activated != RT_TRUE)
  412. {
  413. rx_dma->activated = RT_TRUE;
  414. RT_ASSERT(serial->ops->dma_transmit != RT_NULL);
  415. serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
  416. }
  417. else result = -RT_EBUSY;
  418. rt_hw_interrupt_enable(level);
  419. if (result == RT_EOK) return length;
  420. rt_set_errno(result);
  421. return 0;
  422. }
  423. else
  424. {
  425. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
  426. rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial);
  427. RT_ASSERT(rx_fifo != RT_NULL);
  428. if (length < (int)fifo_recved_len)
  429. recv_len = length;
  430. else
  431. recv_len = fifo_recved_len;
  432. if (rx_fifo->get_index + recv_len < serial->config.bufsz)
  433. rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len);
  434. else
  435. {
  436. rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index,
  437. serial->config.bufsz - rx_fifo->get_index);
  438. rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer,
  439. recv_len + rx_fifo->get_index - serial->config.bufsz);
  440. }
  441. rt_dma_recv_update_get_index(serial, recv_len);
  442. rt_hw_interrupt_enable(level);
  443. return recv_len;
  444. }
  445. }
  446. rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
  447. {
  448. rt_base_t level;
  449. rt_err_t result;
  450. struct rt_serial_tx_dma *tx_dma;
  451. tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx);
  452. result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER);
  453. if (result == RT_EOK)
  454. {
  455. level = rt_hw_interrupt_disable();
  456. if (tx_dma->activated != RT_TRUE)
  457. {
  458. tx_dma->activated = RT_TRUE;
  459. rt_hw_interrupt_enable(level);
  460. /* make a DMA transfer */
  461. serial->ops->dma_transmit(serial, (rt_uint8_t *)data, length, RT_SERIAL_DMA_TX);
  462. }
  463. else
  464. {
  465. rt_hw_interrupt_enable(level);
  466. }
  467. return length;
  468. }
  469. else
  470. {
  471. rt_set_errno(result);
  472. return 0;
  473. }
  474. }
  475. #endif /* RT_SERIAL_USING_DMA */
  476. /* RT-Thread Device Interface */
  477. /*
  478. * This function initializes serial device.
  479. */
  480. static rt_err_t rt_serial_init(struct rt_device *dev)
  481. {
  482. rt_err_t result = RT_EOK;
  483. struct rt_serial_device *serial;
  484. RT_ASSERT(dev != RT_NULL);
  485. serial = (struct rt_serial_device *)dev;
  486. /* initialize rx/tx */
  487. serial->serial_rx = RT_NULL;
  488. serial->serial_tx = RT_NULL;
  489. rt_memset(&serial->rx_notify, 0, sizeof(struct rt_device_notify));
  490. /* apply configuration */
  491. if (serial->ops->configure)
  492. result = serial->ops->configure(serial, &serial->config);
  493. return result;
  494. }
  495. static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
  496. {
  497. rt_uint16_t stream_flag = 0;
  498. struct rt_serial_device *serial;
  499. RT_ASSERT(dev != RT_NULL);
  500. serial = (struct rt_serial_device *)dev;
  501. LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
  502. dev, oflag);
  503. /* check device flag with the open flag */
  504. if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
  505. return -RT_EIO;
  506. if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
  507. return -RT_EIO;
  508. if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
  509. return -RT_EIO;
  510. if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
  511. return -RT_EIO;
  512. /* keep steam flag */
  513. if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM))
  514. stream_flag = RT_DEVICE_FLAG_STREAM;
  515. /* get open flags */
  516. dev->open_flag = oflag & 0xff;
  517. /* initialize the Rx/Tx structure according to open flag */
  518. if (serial->serial_rx == RT_NULL)
  519. {
  520. if (oflag & RT_DEVICE_FLAG_INT_RX)
  521. {
  522. struct rt_serial_rx_fifo* rx_fifo;
  523. rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
  524. serial->config.bufsz);
  525. RT_ASSERT(rx_fifo != RT_NULL);
  526. rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
  527. rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
  528. rx_fifo->put_index = 0;
  529. rx_fifo->get_index = 0;
  530. rx_fifo->is_full = RT_FALSE;
  531. serial->serial_rx = rx_fifo;
  532. dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
  533. /* configure low level device */
  534. serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
  535. }
  536. #ifdef RT_SERIAL_USING_DMA
  537. else if (oflag & RT_DEVICE_FLAG_DMA_RX)
  538. {
  539. if (serial->config.bufsz == 0) {
  540. struct rt_serial_rx_dma* rx_dma;
  541. rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma));
  542. RT_ASSERT(rx_dma != RT_NULL);
  543. rx_dma->activated = RT_FALSE;
  544. serial->serial_rx = rx_dma;
  545. } else {
  546. struct rt_serial_rx_fifo* rx_fifo;
  547. rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
  548. serial->config.bufsz);
  549. RT_ASSERT(rx_fifo != RT_NULL);
  550. rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
  551. rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
  552. rx_fifo->put_index = 0;
  553. rx_fifo->get_index = 0;
  554. rx_fifo->is_full = RT_FALSE;
  555. serial->serial_rx = rx_fifo;
  556. /* configure fifo address and length to low level device */
  557. serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX);
  558. }
  559. dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
  560. }
  561. #endif /* RT_SERIAL_USING_DMA */
  562. else
  563. {
  564. serial->serial_rx = RT_NULL;
  565. }
  566. }
  567. else
  568. {
  569. if (oflag & RT_DEVICE_FLAG_INT_RX)
  570. {
  571. dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
  572. }
  573. #ifdef RT_SERIAL_USING_DMA
  574. else if (oflag & RT_DEVICE_FLAG_DMA_RX)
  575. {
  576. dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
  577. }
  578. #endif /* RT_SERIAL_USING_DMA */
  579. }
  580. if (serial->serial_tx == RT_NULL)
  581. {
  582. if (oflag & RT_DEVICE_FLAG_INT_TX)
  583. {
  584. struct rt_serial_tx_fifo *tx_fifo;
  585. tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc(sizeof(struct rt_serial_tx_fifo));
  586. RT_ASSERT(tx_fifo != RT_NULL);
  587. rt_completion_init(&(tx_fifo->completion));
  588. serial->serial_tx = tx_fifo;
  589. dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
  590. /* configure low level device */
  591. serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
  592. }
  593. #ifdef RT_SERIAL_USING_DMA
  594. else if (oflag & RT_DEVICE_FLAG_DMA_TX)
  595. {
  596. struct rt_serial_tx_dma* tx_dma;
  597. tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
  598. RT_ASSERT(tx_dma != RT_NULL);
  599. tx_dma->activated = RT_FALSE;
  600. rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
  601. serial->serial_tx = tx_dma;
  602. dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
  603. /* configure low level device */
  604. serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_DEVICE_FLAG_DMA_TX);
  605. }
  606. #endif /* RT_SERIAL_USING_DMA */
  607. else
  608. {
  609. serial->serial_tx = RT_NULL;
  610. }
  611. }
  612. else
  613. {
  614. if (oflag & RT_DEVICE_FLAG_INT_TX)
  615. {
  616. dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
  617. }
  618. #ifdef RT_SERIAL_USING_DMA
  619. else if (oflag & RT_DEVICE_FLAG_DMA_TX)
  620. {
  621. dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
  622. }
  623. #endif /* RT_SERIAL_USING_DMA */
  624. }
  625. /* set stream flag */
  626. dev->open_flag |= stream_flag;
  627. return RT_EOK;
  628. }
  629. static rt_err_t rt_serial_close(struct rt_device *dev)
  630. {
  631. struct rt_serial_device *serial;
  632. RT_ASSERT(dev != RT_NULL);
  633. serial = (struct rt_serial_device *)dev;
  634. /* this device has more reference count */
  635. if (dev->ref_count > 1) return RT_EOK;
  636. if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
  637. {
  638. struct rt_serial_rx_fifo* rx_fifo;
  639. rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
  640. RT_ASSERT(rx_fifo != RT_NULL);
  641. rt_free(rx_fifo);
  642. serial->serial_rx = RT_NULL;
  643. dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
  644. /* configure low level device */
  645. serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
  646. }
  647. #ifdef RT_SERIAL_USING_DMA
  648. else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
  649. {
  650. if (serial->config.bufsz == 0) {
  651. struct rt_serial_rx_dma* rx_dma;
  652. rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
  653. RT_ASSERT(rx_dma != RT_NULL);
  654. rt_free(rx_dma);
  655. } else {
  656. struct rt_serial_rx_fifo* rx_fifo;
  657. rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
  658. RT_ASSERT(rx_fifo != RT_NULL);
  659. rt_free(rx_fifo);
  660. }
  661. serial->serial_rx = RT_NULL;
  662. dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
  663. /* configure low level device */
  664. serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
  665. }
  666. #endif /* RT_SERIAL_USING_DMA */
  667. if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
  668. {
  669. struct rt_serial_tx_fifo* tx_fifo;
  670. tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
  671. RT_ASSERT(tx_fifo != RT_NULL);
  672. rt_free(tx_fifo);
  673. serial->serial_tx = RT_NULL;
  674. dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
  675. /* configure low level device */
  676. serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
  677. }
  678. #ifdef RT_SERIAL_USING_DMA
  679. else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
  680. {
  681. struct rt_serial_tx_dma* tx_dma;
  682. tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx;
  683. RT_ASSERT(tx_dma != RT_NULL);
  684. rt_data_queue_deinit(&(tx_dma->data_queue));
  685. rt_free(tx_dma);
  686. serial->serial_tx = RT_NULL;
  687. dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
  688. /* configure low level device */
  689. serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_TX);
  690. }
  691. serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
  692. dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
  693. #endif /* RT_SERIAL_USING_DMA */
  694. return RT_EOK;
  695. }
  696. static rt_size_t rt_serial_read(struct rt_device *dev,
  697. rt_off_t pos,
  698. void *buffer,
  699. rt_size_t size)
  700. {
  701. struct rt_serial_device *serial;
  702. RT_ASSERT(dev != RT_NULL);
  703. if (size == 0) return 0;
  704. serial = (struct rt_serial_device *)dev;
  705. if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
  706. {
  707. return _serial_int_rx(serial, (rt_uint8_t *)buffer, size);
  708. }
  709. #ifdef RT_SERIAL_USING_DMA
  710. else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
  711. {
  712. return _serial_dma_rx(serial, (rt_uint8_t *)buffer, size);
  713. }
  714. #endif /* RT_SERIAL_USING_DMA */
  715. return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size);
  716. }
  717. static rt_size_t rt_serial_write(struct rt_device *dev,
  718. rt_off_t pos,
  719. const void *buffer,
  720. rt_size_t size)
  721. {
  722. struct rt_serial_device *serial;
  723. RT_ASSERT(dev != RT_NULL);
  724. if (size == 0) return 0;
  725. serial = (struct rt_serial_device *)dev;
  726. if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
  727. {
  728. return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size);
  729. }
  730. #ifdef RT_SERIAL_USING_DMA
  731. else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
  732. {
  733. return _serial_dma_tx(serial, (const rt_uint8_t *)buffer, size);
  734. }
  735. #endif /* RT_SERIAL_USING_DMA */
  736. else
  737. {
  738. return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size);
  739. }
  740. }
  741. static rt_err_t rt_serial_control(struct rt_device *dev,
  742. int cmd,
  743. void *args)
  744. {
  745. rt_err_t ret = RT_EOK;
  746. struct rt_serial_device *serial;
  747. RT_ASSERT(dev != RT_NULL);
  748. serial = (struct rt_serial_device *)dev;
  749. switch (cmd)
  750. {
  751. case RT_DEVICE_CTRL_SUSPEND:
  752. /* suspend device */
  753. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  754. break;
  755. case RT_DEVICE_CTRL_RESUME:
  756. /* resume device */
  757. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  758. break;
  759. case RT_DEVICE_CTRL_CONFIG:
  760. if (args)
  761. {
  762. struct serial_configure *pconfig = (struct serial_configure *) args;
  763. if (pconfig->bufsz != serial->config.bufsz && serial->parent.ref_count)
  764. {
  765. /*can not change buffer size*/
  766. return RT_EBUSY;
  767. }
  768. /* set serial configure */
  769. serial->config = *pconfig;
  770. if (serial->parent.ref_count)
  771. {
  772. /* serial device has been opened, to configure it */
  773. serial->ops->configure(serial, (struct serial_configure *) args);
  774. }
  775. }
  776. break;
  777. case RT_DEVICE_CTRL_NOTIFY_SET:
  778. if (args)
  779. {
  780. rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify));
  781. }
  782. break;
  783. case RT_DEVICE_CTRL_CONSOLE_OFLAG:
  784. if (args)
  785. {
  786. *(rt_uint16_t*)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM;
  787. }
  788. break;
  789. #ifdef RT_USING_POSIX
  790. case FIONREAD:
  791. {
  792. rt_size_t recved = 0;
  793. rt_base_t level;
  794. level = rt_hw_interrupt_disable();
  795. recved = _serial_fifo_calc_recved_len(serial);
  796. rt_hw_interrupt_enable(level);
  797. *(rt_size_t *)args = recved;
  798. }
  799. break;
  800. #endif
  801. default :
  802. /* control device */
  803. ret = serial->ops->control(serial, cmd, args);
  804. break;
  805. }
  806. return ret;
  807. }
  808. #ifdef RT_USING_DEVICE_OPS
  809. const static struct rt_device_ops serial_ops =
  810. {
  811. rt_serial_init,
  812. rt_serial_open,
  813. rt_serial_close,
  814. rt_serial_read,
  815. rt_serial_write,
  816. rt_serial_control
  817. };
  818. #endif
  819. /*
  820. * serial register
  821. */
  822. rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
  823. const char *name,
  824. rt_uint32_t flag,
  825. void *data)
  826. {
  827. rt_err_t ret;
  828. struct rt_device *device;
  829. RT_ASSERT(serial != RT_NULL);
  830. device = &(serial->parent);
  831. device->type = RT_Device_Class_Char;
  832. device->rx_indicate = RT_NULL;
  833. device->tx_complete = RT_NULL;
  834. #ifdef RT_USING_DEVICE_OPS
  835. device->ops = &serial_ops;
  836. #else
  837. device->init = rt_serial_init;
  838. device->open = rt_serial_open;
  839. device->close = rt_serial_close;
  840. device->read = rt_serial_read;
  841. device->write = rt_serial_write;
  842. device->control = rt_serial_control;
  843. #endif
  844. device->user_data = data;
  845. /* register a character device */
  846. ret = rt_device_register(device, name, flag);
  847. #if defined(RT_USING_POSIX)
  848. /* set fops */
  849. device->fops = &_serial_fops;
  850. #endif
  851. return ret;
  852. }
  853. /* ISR for serial interrupt */
  854. void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
  855. {
  856. switch (event & 0xff)
  857. {
  858. case RT_SERIAL_EVENT_RX_IND:
  859. {
  860. int ch = -1;
  861. rt_base_t level;
  862. struct rt_serial_rx_fifo* rx_fifo;
  863. /* interrupt mode receive */
  864. rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
  865. RT_ASSERT(rx_fifo != RT_NULL);
  866. while (1)
  867. {
  868. ch = serial->ops->getc(serial);
  869. if (ch == -1) break;
  870. /* disable interrupt */
  871. level = rt_hw_interrupt_disable();
  872. rx_fifo->buffer[rx_fifo->put_index] = ch;
  873. rx_fifo->put_index += 1;
  874. if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
  875. /* if the next position is read index, discard this 'read char' */
  876. if (rx_fifo->put_index == rx_fifo->get_index)
  877. {
  878. rx_fifo->get_index += 1;
  879. rx_fifo->is_full = RT_TRUE;
  880. if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
  881. _serial_check_buffer_size();
  882. }
  883. /* enable interrupt */
  884. rt_hw_interrupt_enable(level);
  885. }
  886. /* invoke callback */
  887. if (serial->parent.rx_indicate != RT_NULL)
  888. {
  889. rt_size_t rx_length;
  890. /* get rx length */
  891. level = rt_hw_interrupt_disable();
  892. rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
  893. (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
  894. rt_hw_interrupt_enable(level);
  895. if (rx_length)
  896. {
  897. serial->parent.rx_indicate(&serial->parent, rx_length);
  898. }
  899. }
  900. if (serial->rx_notify.notify)
  901. {
  902. serial->rx_notify.notify(serial->rx_notify.dev);
  903. }
  904. break;
  905. }
  906. case RT_SERIAL_EVENT_TX_DONE:
  907. {
  908. struct rt_serial_tx_fifo* tx_fifo;
  909. tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
  910. rt_completion_done(&(tx_fifo->completion));
  911. break;
  912. }
  913. #ifdef RT_SERIAL_USING_DMA
  914. case RT_SERIAL_EVENT_TX_DMADONE:
  915. {
  916. const void *data_ptr;
  917. rt_size_t data_size;
  918. const void *last_data_ptr;
  919. struct rt_serial_tx_dma *tx_dma;
  920. tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
  921. rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
  922. if (rt_data_queue_peek(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
  923. {
  924. /* transmit next data node */
  925. tx_dma->activated = RT_TRUE;
  926. serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX);
  927. }
  928. else
  929. {
  930. tx_dma->activated = RT_FALSE;
  931. }
  932. /* invoke callback */
  933. if (serial->parent.tx_complete != RT_NULL)
  934. {
  935. serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr);
  936. }
  937. break;
  938. }
  939. case RT_SERIAL_EVENT_RX_DMADONE:
  940. {
  941. int length;
  942. rt_base_t level;
  943. /* get DMA rx length */
  944. length = (event & (~0xff)) >> 8;
  945. if (serial->config.bufsz == 0)
  946. {
  947. struct rt_serial_rx_dma* rx_dma;
  948. rx_dma = (struct rt_serial_rx_dma*) serial->serial_rx;
  949. RT_ASSERT(rx_dma != RT_NULL);
  950. RT_ASSERT(serial->parent.rx_indicate != RT_NULL);
  951. serial->parent.rx_indicate(&(serial->parent), length);
  952. rx_dma->activated = RT_FALSE;
  953. }
  954. else
  955. {
  956. /* disable interrupt */
  957. level = rt_hw_interrupt_disable();
  958. /* update fifo put index */
  959. rt_dma_recv_update_put_index(serial, length);
  960. /* calculate received total length */
  961. length = rt_dma_calc_recved_len(serial);
  962. /* enable interrupt */
  963. rt_hw_interrupt_enable(level);
  964. /* invoke callback */
  965. if (serial->parent.rx_indicate != RT_NULL)
  966. {
  967. serial->parent.rx_indicate(&(serial->parent), length);
  968. }
  969. }
  970. break;
  971. }
  972. #endif /* RT_SERIAL_USING_DMA */
  973. }
  974. }