1 /*
2 * Copyright (c) 2006-2024, 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 * 2020-12-14 Meco Man implement function of setting window's size(TIOCSWINSZ)
28 * 2021-08-22 Meco Man implement function of getting window's size(TIOCGWINSZ)
29 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
30 * 2024-11-25 zhujiale add bypass mode
31 */
32
33 #include <rthw.h>
34 #include <rtthread.h>
35 #include <rtdevice.h>
36
37 #define DBG_TAG "UART"
38 #define DBG_LVL DBG_INFO
39 #include <rtdbg.h>
40
41 #ifdef RT_USING_POSIX_STDIO
42 #include <dfs_file.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <poll.h>
46 #include <sys/ioctl.h>
47
48 #ifdef RT_USING_POSIX_TERMIOS
49 #include <termios.h>
50 #endif
51
52 /* it's possible the 'getc/putc' is defined by stdio.h in gcc/newlib. */
53 #ifdef getc
54 #undef getc
55 #endif
56
57 #ifdef putc
58 #undef putc
59 #endif
60
61 RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind);
62
serial_fops_rx_ind(rt_device_t dev,rt_size_t size)63 static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
64 {
65 rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
66
67 RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
68
69 return RT_EOK;
70 }
71
72 /* fops for serial */
serial_fops_open(struct dfs_file * fd)73 static int serial_fops_open(struct dfs_file *fd)
74 {
75 rt_err_t ret = 0;
76 rt_uint16_t flags = 0;
77 rt_device_t device;
78
79 device = (rt_device_t)fd->vnode->data;
80 RT_ASSERT(device != RT_NULL);
81
82 switch (fd->flags & O_ACCMODE)
83 {
84 case O_RDONLY:
85 LOG_D("fops open: O_RDONLY!");
86 flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY;
87 break;
88 case O_WRONLY:
89 LOG_D("fops open: O_WRONLY!");
90 flags = RT_DEVICE_FLAG_WRONLY;
91 break;
92 case O_RDWR:
93 LOG_D("fops open: O_RDWR!");
94 flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR;
95 break;
96 default:
97 LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
98 break;
99 }
100
101 if ((fd->flags & O_ACCMODE) != O_WRONLY)
102 rt_device_set_rx_indicate(device, serial_fops_rx_ind);
103 ret = rt_device_open(device, flags);
104 if (ret == RT_EOK) return 0;
105
106 return ret;
107 }
108
serial_fops_close(struct dfs_file * fd)109 static int serial_fops_close(struct dfs_file *fd)
110 {
111 rt_device_t device;
112
113 device = (rt_device_t)fd->vnode->data;
114
115 rt_device_set_rx_indicate(device, RT_NULL);
116 rt_device_close(device);
117
118 return 0;
119 }
120
serial_fops_ioctl(struct dfs_file * fd,int cmd,void * args)121 static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
122 {
123 rt_device_t device;
124 int flags = (int)(rt_base_t)args;
125 int mask = O_NONBLOCK | O_APPEND;
126
127 device = (rt_device_t)fd->vnode->data;
128 switch (cmd)
129 {
130 case FIONREAD:
131 break;
132 case FIONWRITE:
133 break;
134 case F_SETFL:
135 flags &= mask;
136 fd->flags &= ~mask;
137 fd->flags |= flags;
138 break;
139 }
140
141 return rt_device_control(device, cmd, args);
142 }
143
144 #ifdef RT_USING_DFS_V2
serial_fops_read(struct dfs_file * fd,void * buf,size_t count,off_t * pos)145 static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos)
146 #else
147 static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
148 #endif
149 {
150 int size = 0;
151 rt_device_t device;
152 int wait_ret;
153
154 device = (rt_device_t)fd->vnode->data;
155
156 do
157 {
158 size = rt_device_read(device, -1, buf, count);
159 if (size <= 0)
160 {
161 if (fd->flags & O_NONBLOCK)
162 {
163 size = -EAGAIN;
164 break;
165 }
166
167 wait_ret = rt_wqueue_wait_interruptible(&(device->wait_queue), 0, RT_WAITING_FOREVER);
168 if (wait_ret != RT_EOK)
169 {
170 break;
171 }
172 }
173 }while (size <= 0);
174
175 if (size < 0)
176 {
177 size = 0;
178 }
179 return size;
180 }
181
182 #ifdef RT_USING_DFS_V2
serial_fops_write(struct dfs_file * fd,const void * buf,size_t count,off_t * pos)183 static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos)
184 #else
185 static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
186 #endif
187 {
188 rt_device_t device;
189
190 device = (rt_device_t)fd->vnode->data;
191 return rt_device_write(device, -1, buf, count);
192 }
193
serial_fops_poll(struct dfs_file * fd,struct rt_pollreq * req)194 static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
195 {
196 int mask = 0;
197 int flags = 0;
198 rt_device_t device;
199 struct rt_serial_device *serial;
200
201 device = (rt_device_t)fd->vnode->data;
202 RT_ASSERT(device != RT_NULL);
203
204 serial = (struct rt_serial_device *)device;
205
206 /* only support POLLIN */
207 flags = fd->flags & O_ACCMODE;
208 if (flags == O_RDONLY || flags == O_RDWR)
209 {
210 rt_base_t level;
211 struct rt_serial_rx_fifo* rx_fifo;
212
213 rt_poll_add(&(device->wait_queue), req);
214
215 rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
216
217 level = rt_spin_lock_irqsave(&(serial->spinlock));
218 if ((rx_fifo->get_index != rx_fifo->put_index) || (rx_fifo->get_index == rx_fifo->put_index && rx_fifo->is_full == RT_TRUE))
219 mask |= POLLIN;
220 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
221 }
222
223 return mask;
224 }
225
226 static const struct dfs_file_ops _serial_fops =
227 {
228 .open = serial_fops_open,
229 .close = serial_fops_close,
230 .ioctl = serial_fops_ioctl,
231 .read = serial_fops_read,
232 .write = serial_fops_write,
233 .poll = serial_fops_poll,
234 };
235 #endif /* RT_USING_POSIX_STDIO */
236
237 /*
238 * Serial poll routines
239 */
_serial_poll_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)240 rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
241 {
242 int ch;
243 int size;
244
245 RT_ASSERT(serial != RT_NULL);
246 size = length;
247
248 while (length)
249 {
250 ch = serial->ops->getc(serial);
251 if (ch == -1) break;
252
253 *data = ch;
254 data ++; length --;
255
256 if(serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
257 {
258 if (ch == '\n') break;
259 }
260 }
261
262 return size - length;
263 }
264
_serial_poll_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)265 rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
266 {
267 int size;
268 RT_ASSERT(serial != RT_NULL);
269
270 size = length;
271 while (length)
272 {
273 /*
274 * to be polite with serial console add a line feed
275 * to the carriage return character
276 */
277 if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
278 {
279 serial->ops->putc(serial, '\r');
280 }
281
282 if(serial->ops->putc(serial, *data) < 0) {
283 break;
284 }
285
286 ++ data;
287 -- length;
288 }
289
290 return size - length;
291 }
292
293 /*
294 * Serial interrupt routines
295 */
_serial_int_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)296 rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
297 {
298 int size;
299 struct rt_serial_rx_fifo* rx_fifo;
300
301 RT_ASSERT(serial != RT_NULL);
302 size = length;
303
304 rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
305 RT_ASSERT(rx_fifo != RT_NULL);
306
307 #ifdef RT_USING_SERIAL_BYPASS
308 if (serial->bypass)
309 {
310 rt_bypass_work_straight(serial);
311 while (length)
312 {
313 rt_uint8_t ch;
314 if (!rt_bypass_getchar(serial, &ch))
315 break;
316
317 *data = ch & 0xff;
318 data++; length--;
319 }
320
321 return size - length;
322 }
323 #endif
324 /* read from software FIFO */
325 while (length)
326 {
327 int ch;
328 rt_base_t level;
329
330 /* disable interrupt */
331 level = rt_spin_lock_irqsave(&(serial->spinlock));
332
333 /* there's no data: */
334 if ((rx_fifo->get_index == rx_fifo->put_index) && (rx_fifo->is_full == RT_FALSE))
335 {
336 /* no data, enable interrupt and break out */
337 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
338 break;
339 }
340
341 /* otherwise there's the data: */
342 ch = rx_fifo->buffer[rx_fifo->get_index];
343 rx_fifo->get_index += 1;
344 if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
345
346 if (rx_fifo->is_full == RT_TRUE)
347 {
348 rx_fifo->is_full = RT_FALSE;
349 }
350
351 /* enable interrupt */
352 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
353
354 *data = ch & 0xff;
355 data ++; length --;
356 }
357
358 return size - length;
359 }
360
_serial_int_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)361 rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
362 {
363 int size;
364 struct rt_serial_tx_fifo *tx;
365
366 RT_ASSERT(serial != RT_NULL);
367
368 size = length;
369 tx = (struct rt_serial_tx_fifo*) serial->serial_tx;
370 RT_ASSERT(tx != RT_NULL);
371
372 while (length)
373 {
374 /*
375 * to be polite with serial console add a line feed
376 * to the carriage return character
377 */
378 if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
379 {
380 if (serial->ops->putc(serial, '\r') == -1)
381 {
382 rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
383 continue;
384 }
385 }
386
387 while (serial->ops->putc(serial, *(char*)data) == -1)
388 {
389 rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
390 }
391
392 data ++; length --;
393 }
394
395 return size - length;
396 }
397
_serial_check_buffer_size(void)398 static void _serial_check_buffer_size(void)
399 {
400 static rt_bool_t already_output = RT_FALSE;
401
402 if (already_output == RT_FALSE)
403 {
404 #if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG)
405 LOG_W("Warning: There is no enough buffer for saving data,"
406 " please increase the RT_SERIAL_RB_BUFSZ option.");
407 #endif
408 already_output = RT_TRUE;
409 }
410 }
411
412 #if defined(RT_USING_POSIX_STDIO) || defined(RT_SERIAL_USING_DMA)
_serial_fifo_calc_recved_len(struct rt_serial_device * serial)413 static rt_ssize_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
414 {
415 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
416
417 RT_ASSERT(rx_fifo != RT_NULL);
418
419 if (rx_fifo->put_index == rx_fifo->get_index)
420 {
421 return (rx_fifo->is_full == RT_FALSE ? 0 : serial->config.bufsz);
422 }
423 else
424 {
425 if (rx_fifo->put_index > rx_fifo->get_index)
426 {
427 return rx_fifo->put_index - rx_fifo->get_index;
428 }
429 else
430 {
431 return serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index);
432 }
433 }
434 }
435 #endif /* RT_USING_POSIX_STDIO || RT_SERIAL_USING_DMA */
436
437 #ifdef RT_SERIAL_USING_DMA
438 /**
439 * Calculate DMA received data length.
440 *
441 * @param serial serial device
442 *
443 * @return length
444 */
rt_dma_calc_recved_len(struct rt_serial_device * serial)445 static rt_ssize_t rt_dma_calc_recved_len(struct rt_serial_device *serial)
446 {
447 return _serial_fifo_calc_recved_len(serial);
448 }
449
450 /**
451 * Read data finish by DMA mode then update the get index for receive fifo.
452 *
453 * @param serial serial device
454 * @param len get data length for this operate
455 */
rt_dma_recv_update_get_index(struct rt_serial_device * serial,rt_size_t len)456 static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_size_t len)
457 {
458 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
459
460 RT_ASSERT(rx_fifo != RT_NULL);
461 RT_ASSERT(len <= rt_dma_calc_recved_len(serial));
462
463 if (rx_fifo->is_full && len != 0) rx_fifo->is_full = RT_FALSE;
464
465 rx_fifo->get_index += (rt_uint16_t)len;
466 if (rx_fifo->get_index >= serial->config.bufsz)
467 {
468 rx_fifo->get_index %= serial->config.bufsz;
469 }
470 }
471
472 /**
473 * DMA received finish then update put index for receive fifo.
474 *
475 * @param serial serial device
476 * @param len received length for this transmit
477 */
rt_dma_recv_update_put_index(struct rt_serial_device * serial,rt_size_t len)478 static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_size_t len)
479 {
480 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
481
482 RT_ASSERT(rx_fifo != RT_NULL);
483
484 if (rx_fifo->get_index <= rx_fifo->put_index)
485 {
486 rx_fifo->put_index += (rt_uint16_t)len;
487 /* beyond the fifo end */
488 if (rx_fifo->put_index >= serial->config.bufsz)
489 {
490 rx_fifo->put_index %= serial->config.bufsz;
491 /* force overwrite get index */
492 if (rx_fifo->put_index >= rx_fifo->get_index)
493 {
494 rx_fifo->is_full = RT_TRUE;
495 }
496 }
497 }
498 else
499 {
500 rx_fifo->put_index += (rt_uint16_t)len;
501 if (rx_fifo->put_index >= rx_fifo->get_index)
502 {
503 /* beyond the fifo end */
504 if (rx_fifo->put_index >= serial->config.bufsz)
505 {
506 rx_fifo->put_index %= serial->config.bufsz;
507 }
508 /* force overwrite get index */
509 rx_fifo->is_full = RT_TRUE;
510 }
511 }
512
513 if(rx_fifo->is_full == RT_TRUE)
514 {
515 _serial_check_buffer_size();
516 rx_fifo->get_index = rx_fifo->put_index;
517 }
518 }
519
520 /*
521 * Serial DMA routines
522 */
_serial_dma_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)523 rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
524 {
525 rt_base_t level;
526
527 RT_ASSERT((serial != RT_NULL) && (data != RT_NULL));
528
529 level = rt_spin_lock_irqsave(&(serial->spinlock));
530
531 if (serial->config.bufsz == 0)
532 {
533 int result = RT_EOK;
534 struct rt_serial_rx_dma *rx_dma;
535
536 rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
537 RT_ASSERT(rx_dma != RT_NULL);
538
539 if (rx_dma->activated != RT_TRUE)
540 {
541 rx_dma->activated = RT_TRUE;
542 RT_ASSERT(serial->ops->dma_transmit != RT_NULL);
543 serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
544 }
545 else result = -RT_EBUSY;
546 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
547
548 if (result == RT_EOK) return length;
549
550 rt_set_errno(result);
551 return 0;
552 }
553 else
554 {
555 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
556 rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial);
557
558 RT_ASSERT(rx_fifo != RT_NULL);
559
560 if (length < (int)fifo_recved_len)
561 recv_len = length;
562 else
563 recv_len = fifo_recved_len;
564
565 if (rx_fifo->get_index + recv_len < serial->config.bufsz)
566 rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len);
567 else
568 {
569 rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index,
570 serial->config.bufsz - rx_fifo->get_index);
571 rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer,
572 recv_len + rx_fifo->get_index - serial->config.bufsz);
573 }
574 rt_dma_recv_update_get_index(serial, recv_len);
575 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
576 return recv_len;
577 }
578 }
579
_serial_dma_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)580 rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
581 {
582 rt_base_t level;
583 rt_err_t result;
584 struct rt_serial_tx_dma *tx_dma;
585
586 tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx);
587
588 result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER);
589 if (result == RT_EOK)
590 {
591 level = rt_spin_lock_irqsave(&(serial->spinlock));
592 if (tx_dma->activated != RT_TRUE)
593 {
594 tx_dma->activated = RT_TRUE;
595 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
596
597 /* make a DMA transfer */
598 serial->ops->dma_transmit(serial, (rt_uint8_t *)data, length, RT_SERIAL_DMA_TX);
599 }
600 else
601 {
602 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
603 }
604
605 return length;
606 }
607 else
608 {
609 rt_set_errno(result);
610 return 0;
611 }
612 }
613 #endif /* RT_SERIAL_USING_DMA */
614
615 /* RT-Thread Device Interface */
616 /*
617 * This function initializes serial device.
618 */
rt_serial_init(struct rt_device * dev)619 static rt_err_t rt_serial_init(struct rt_device *dev)
620 {
621 rt_err_t result = RT_EOK;
622 struct rt_serial_device *serial;
623
624 RT_ASSERT(dev != RT_NULL);
625 serial = (struct rt_serial_device *)dev;
626
627 /* initialize rx/tx */
628 serial->serial_rx = RT_NULL;
629 serial->serial_tx = RT_NULL;
630
631 rt_memset(&serial->rx_notify, 0, sizeof(struct rt_device_notify));
632
633 /* apply configuration */
634 if (serial->ops->configure)
635 result = serial->ops->configure(serial, &serial->config);
636
637 return result;
638 }
639
rt_serial_open(struct rt_device * dev,rt_uint16_t oflag)640 static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
641 {
642 rt_uint16_t stream_flag = 0;
643 struct rt_serial_device *serial;
644
645 RT_ASSERT(dev != RT_NULL);
646 serial = (struct rt_serial_device *)dev;
647
648 LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
649 dev, oflag);
650 /* check device flag with the open flag */
651 if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
652 return -RT_EIO;
653 if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
654 return -RT_EIO;
655 if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
656 return -RT_EIO;
657 if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
658 return -RT_EIO;
659
660 /* keep steam flag */
661 if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM))
662 stream_flag = RT_DEVICE_FLAG_STREAM;
663
664 /* get open flags */
665 dev->open_flag = oflag & 0xff;
666
667 #ifdef RT_USING_PINCTRL
668 /* initialize iomux in DM */
669 rt_pin_ctrl_confs_apply_by_name(dev, RT_NULL);
670 #endif
671
672 /* initialize the Rx/Tx structure according to open flag */
673 if (serial->serial_rx == RT_NULL)
674 {
675 if (oflag & RT_DEVICE_FLAG_INT_RX)
676 {
677 struct rt_serial_rx_fifo* rx_fifo;
678
679 rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
680 serial->config.bufsz);
681 RT_ASSERT(rx_fifo != RT_NULL);
682 rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
683 rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
684 rx_fifo->put_index = 0;
685 rx_fifo->get_index = 0;
686 rx_fifo->is_full = RT_FALSE;
687
688 serial->serial_rx = rx_fifo;
689 dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
690 /* configure low level device */
691 serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
692 }
693 #ifdef RT_SERIAL_USING_DMA
694 else if (oflag & RT_DEVICE_FLAG_DMA_RX)
695 {
696 if (serial->config.bufsz == 0) {
697 struct rt_serial_rx_dma* rx_dma;
698
699 rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma));
700 RT_ASSERT(rx_dma != RT_NULL);
701 rx_dma->activated = RT_FALSE;
702
703 serial->serial_rx = rx_dma;
704 } else {
705 struct rt_serial_rx_fifo* rx_fifo;
706
707 rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
708 serial->config.bufsz);
709 RT_ASSERT(rx_fifo != RT_NULL);
710 rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
711 rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
712 rx_fifo->put_index = 0;
713 rx_fifo->get_index = 0;
714 rx_fifo->is_full = RT_FALSE;
715 serial->serial_rx = rx_fifo;
716 /* configure fifo address and length to low level device */
717 serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX);
718 }
719 dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
720 }
721 #endif /* RT_SERIAL_USING_DMA */
722 else
723 {
724 serial->serial_rx = RT_NULL;
725 }
726 }
727 else
728 {
729 if (oflag & RT_DEVICE_FLAG_INT_RX)
730 dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
731 #ifdef RT_SERIAL_USING_DMA
732 else if (oflag & RT_DEVICE_FLAG_DMA_RX)
733 dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
734 #endif /* RT_SERIAL_USING_DMA */
735 }
736
737 if (serial->serial_tx == RT_NULL)
738 {
739 if (oflag & RT_DEVICE_FLAG_INT_TX)
740 {
741 struct rt_serial_tx_fifo *tx_fifo;
742
743 tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc(sizeof(struct rt_serial_tx_fifo));
744 RT_ASSERT(tx_fifo != RT_NULL);
745
746 rt_completion_init(&(tx_fifo->completion));
747 serial->serial_tx = tx_fifo;
748
749 dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
750 /* configure low level device */
751 serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
752 }
753 #ifdef RT_SERIAL_USING_DMA
754 else if (oflag & RT_DEVICE_FLAG_DMA_TX)
755 {
756 struct rt_serial_tx_dma* tx_dma;
757
758 tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
759 RT_ASSERT(tx_dma != RT_NULL);
760 tx_dma->activated = RT_FALSE;
761
762 rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
763 serial->serial_tx = tx_dma;
764
765 dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
766 /* configure low level device */
767 serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_DEVICE_FLAG_DMA_TX);
768 }
769 #endif /* RT_SERIAL_USING_DMA */
770 else
771 {
772 serial->serial_tx = RT_NULL;
773 }
774 }
775 else
776 {
777 if (oflag & RT_DEVICE_FLAG_INT_TX)
778 dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
779 #ifdef RT_SERIAL_USING_DMA
780 else if (oflag & RT_DEVICE_FLAG_DMA_TX)
781 dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
782 #endif /* RT_SERIAL_USING_DMA */
783 }
784
785 /* set stream flag */
786 dev->open_flag |= stream_flag;
787
788 return RT_EOK;
789 }
790
rt_serial_close(struct rt_device * dev)791 static rt_err_t rt_serial_close(struct rt_device *dev)
792 {
793 struct rt_serial_device *serial;
794
795 RT_ASSERT(dev != RT_NULL);
796 serial = (struct rt_serial_device *)dev;
797
798 /* this device has more reference count */
799 if (dev->ref_count > 1) return RT_EOK;
800
801 if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
802 {
803 struct rt_serial_rx_fifo* rx_fifo;
804
805 /* configure low level device */
806 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
807 dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
808
809 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
810 RT_ASSERT(rx_fifo != RT_NULL);
811
812 rt_free(rx_fifo);
813 serial->serial_rx = RT_NULL;
814
815 }
816 #ifdef RT_SERIAL_USING_DMA
817 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
818 {
819 /* configure low level device */
820 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
821 dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
822
823 if (serial->config.bufsz == 0)
824 {
825 struct rt_serial_rx_dma* rx_dma;
826
827 rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
828 RT_ASSERT(rx_dma != RT_NULL);
829
830 rt_free(rx_dma);
831 }
832 else
833 {
834 struct rt_serial_rx_fifo* rx_fifo;
835
836 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
837 RT_ASSERT(rx_fifo != RT_NULL);
838
839 rt_free(rx_fifo);
840 }
841 serial->serial_rx = RT_NULL;
842
843 }
844 #endif /* RT_SERIAL_USING_DMA */
845
846 if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
847 {
848 struct rt_serial_tx_fifo* tx_fifo;
849
850 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
851 dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
852
853 tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
854 RT_ASSERT(tx_fifo != RT_NULL);
855
856 rt_free(tx_fifo);
857 serial->serial_tx = RT_NULL;
858
859 /* configure low level device */
860 }
861 #ifdef RT_SERIAL_USING_DMA
862 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
863 {
864 struct rt_serial_tx_dma* tx_dma;
865
866 /* configure low level device */
867 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_TX);
868 dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
869
870 tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx;
871 RT_ASSERT(tx_dma != RT_NULL);
872
873 rt_data_queue_deinit(&(tx_dma->data_queue));
874
875 rt_free(tx_dma);
876 serial->serial_tx = RT_NULL;
877
878 }
879 #endif /* RT_SERIAL_USING_DMA */
880
881 serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
882 dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
883
884 return RT_EOK;
885 }
886
rt_serial_read(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)887 static rt_ssize_t rt_serial_read(struct rt_device *dev,
888 rt_off_t pos,
889 void *buffer,
890 rt_size_t size)
891 {
892 struct rt_serial_device *serial;
893
894 RT_ASSERT(dev != RT_NULL);
895 if (size == 0) return 0;
896
897 serial = (struct rt_serial_device *)dev;
898
899 if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
900 {
901 return _serial_int_rx(serial, (rt_uint8_t *)buffer, size);
902 }
903 #ifdef RT_SERIAL_USING_DMA
904 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
905 {
906 return _serial_dma_rx(serial, (rt_uint8_t *)buffer, size);
907 }
908 #endif /* RT_SERIAL_USING_DMA */
909
910 return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size);
911 }
912
rt_serial_write(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)913 static rt_ssize_t rt_serial_write(struct rt_device *dev,
914 rt_off_t pos,
915 const void *buffer,
916 rt_size_t size)
917 {
918 struct rt_serial_device *serial;
919
920 RT_ASSERT(dev != RT_NULL);
921 if (size == 0) return 0;
922
923 serial = (struct rt_serial_device *)dev;
924
925 if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
926 {
927 return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size);
928 }
929 #ifdef RT_SERIAL_USING_DMA
930 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
931 {
932 return _serial_dma_tx(serial, (const rt_uint8_t *)buffer, size);
933 }
934 #endif /* RT_SERIAL_USING_DMA */
935 else
936 {
937 return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size);
938 }
939 }
940
941 #if defined(RT_USING_POSIX_TERMIOS)
942 struct speed_baudrate_item
943 {
944 speed_t speed;
945 int baudrate;
946 };
947
948 static const struct speed_baudrate_item _tbl[] =
949 {
950 {B2400, BAUD_RATE_2400},
951 {B4800, BAUD_RATE_4800},
952 {B9600, BAUD_RATE_9600},
953 {B19200, BAUD_RATE_19200},
954 {B38400, BAUD_RATE_38400},
955 {B57600, BAUD_RATE_57600},
956 {B115200, BAUD_RATE_115200},
957 {B230400, BAUD_RATE_230400},
958 {B460800, BAUD_RATE_460800},
959 {B500000, BAUD_RATE_500000},
960 {B576000, BAUD_RATE_576000},
961 {B921600, BAUD_RATE_921600},
962 {B1000000, BAUD_RATE_1000000},
963 {B1152000, BAUD_RATE_1152000},
964 {B1500000, BAUD_RATE_1500000},
965 {B2000000, BAUD_RATE_2000000},
966 {B2500000, BAUD_RATE_2500000},
967 {B3000000, BAUD_RATE_3000000},
968 {B3500000, BAUD_RATE_3500000},
969 {B4000000, BAUD_RATE_4000000},
970 };
971
_get_speed(int baudrate)972 static speed_t _get_speed(int baudrate)
973 {
974 size_t index;
975
976 for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++)
977 {
978 if (_tbl[index].baudrate == baudrate)
979 return _tbl[index].speed;
980 }
981
982 return B0;
983 }
984
_get_baudrate(speed_t speed)985 static int _get_baudrate(speed_t speed)
986 {
987 size_t index;
988
989 for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++)
990 {
991 if (_tbl[index].speed == speed)
992 return _tbl[index].baudrate;
993 }
994
995 return 0;
996 }
997
_tc_flush(struct rt_serial_device * serial,int queue)998 static void _tc_flush(struct rt_serial_device *serial, int queue)
999 {
1000 rt_base_t level;
1001 int ch = -1;
1002 struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
1003 struct rt_device *device = RT_NULL;
1004
1005 RT_ASSERT(serial != RT_NULL);
1006
1007 device = &(serial->parent);
1008 rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
1009
1010 switch(queue)
1011 {
1012 case TCIFLUSH:
1013 case TCIOFLUSH:
1014
1015 RT_ASSERT(rx_fifo != RT_NULL);
1016
1017 if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX))
1018 {
1019 RT_ASSERT(RT_NULL != rx_fifo);
1020 level = rt_spin_lock_irqsave(&(serial->spinlock));
1021 rx_fifo->get_index = rx_fifo->put_index;
1022 rx_fifo->is_full = RT_FALSE;
1023 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
1024 }
1025 else
1026 {
1027 while (1)
1028 {
1029 ch = serial->ops->getc(serial);
1030 if (ch == -1) break;
1031 }
1032 }
1033
1034 break;
1035
1036 case TCOFLUSH:
1037 break;
1038 }
1039
1040 }
1041
_termio_to_termios(const struct termio * termio,struct termios * termios)1042 static inline int _termio_to_termios(const struct termio *termio, struct termios *termios)
1043 {
1044 termios->c_iflag = termio->c_iflag;
1045 termios->c_oflag = termio->c_oflag;
1046 termios->c_cflag = termio->c_cflag;
1047 termios->c_lflag = termio->c_lflag;
1048 termios->c_line = termio->c_line;
1049 rt_memcpy(termios->c_cc, termio->c_cc, NCC);
1050
1051 return 0;
1052 }
1053
_termios_to_termio(const struct termios * termios,struct termio * termio)1054 static inline int _termios_to_termio(const struct termios *termios, struct termio *termio)
1055 {
1056 termio->c_iflag = (unsigned short)termios->c_iflag;
1057 termio->c_oflag = (unsigned short)termios->c_oflag;
1058 termio->c_cflag = (unsigned short)termios->c_cflag;
1059 termio->c_lflag = (unsigned short)termios->c_lflag;
1060 termio->c_line = termios->c_line;
1061 rt_memcpy(termio->c_cc, termios->c_cc, NCC);
1062
1063 return 0;
1064 }
1065 #endif /* RT_USING_POSIX_TERMIOS */
1066
rt_serial_control(struct rt_device * dev,int cmd,void * args)1067 static rt_err_t rt_serial_control(struct rt_device *dev,
1068 int cmd,
1069 void *args)
1070 {
1071 rt_err_t ret = RT_EOK;
1072 struct rt_serial_device *serial;
1073
1074 RT_ASSERT(dev != RT_NULL);
1075 serial = (struct rt_serial_device *)dev;
1076
1077 switch (cmd)
1078 {
1079 case RT_DEVICE_CTRL_SUSPEND:
1080 /* suspend device */
1081 dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
1082 break;
1083
1084 case RT_DEVICE_CTRL_RESUME:
1085 /* resume device */
1086 dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
1087 break;
1088
1089 case RT_DEVICE_CTRL_CONFIG:
1090 if (args)
1091 {
1092 struct serial_configure *pconfig = (struct serial_configure *) args;
1093 if (pconfig->bufsz != serial->config.bufsz && serial->parent.ref_count)
1094 {
1095 /*can not change buffer size*/
1096 return -RT_EBUSY;
1097 }
1098 /* set serial configure */
1099 serial->config = *pconfig;
1100 if (serial->parent.ref_count)
1101 {
1102 /* serial device has been opened, to configure it */
1103 serial->ops->configure(serial, (struct serial_configure *) args);
1104 }
1105 }
1106 break;
1107 case RT_DEVICE_CTRL_NOTIFY_SET:
1108 if (args)
1109 {
1110 rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify));
1111 }
1112 break;
1113
1114 case RT_DEVICE_CTRL_CONSOLE_OFLAG:
1115 if (args)
1116 {
1117 *(rt_uint16_t*)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM;
1118 }
1119 break;
1120 #ifdef RT_USING_POSIX_STDIO
1121 #if defined(RT_USING_POSIX_TERMIOS)
1122 case TCGETA:
1123 case TCGETS:
1124 {
1125 struct termios *tio, tmp;
1126
1127 if (cmd == TCGETS)
1128 {
1129 tio = (struct termios*)args;
1130 }
1131 else
1132 {
1133 tio = &tmp;
1134 }
1135
1136 if (tio == RT_NULL) return -RT_EINVAL;
1137
1138 tio->c_iflag = 0;
1139 tio->c_oflag = 0;
1140 tio->c_lflag = 0;
1141
1142 /* update oflag for console device */
1143 if (rt_console_get_device() == dev)
1144 tio->c_oflag = OPOST | ONLCR;
1145
1146 /* set cflag */
1147 tio->c_cflag = 0;
1148 if (serial->config.data_bits == DATA_BITS_5)
1149 tio->c_cflag = CS5;
1150 else if (serial->config.data_bits == DATA_BITS_6)
1151 tio->c_cflag = CS6;
1152 else if (serial->config.data_bits == DATA_BITS_7)
1153 tio->c_cflag = CS7;
1154 else if (serial->config.data_bits == DATA_BITS_8)
1155 tio->c_cflag = CS8;
1156
1157 if (serial->config.stop_bits == STOP_BITS_2)
1158 tio->c_cflag |= CSTOPB;
1159
1160 if (serial->config.parity == PARITY_EVEN)
1161 tio->c_cflag |= PARENB;
1162 else if (serial->config.parity == PARITY_ODD)
1163 tio->c_cflag |= (PARODD | PARENB);
1164
1165 cfsetospeed(tio, _get_speed(serial->config.baud_rate));
1166
1167 if (cmd == TCGETA)
1168 {
1169 _termios_to_termio(tio, args);
1170 }
1171 }
1172 break;
1173 case TCSETAW:
1174 case TCSETAF:
1175 case TCSETA:
1176 case TCSETSW:
1177 case TCSETSF:
1178 case TCSETS:
1179 {
1180 int baudrate;
1181 struct serial_configure config;
1182 struct termios *tio, tmp;
1183
1184 if ((cmd >= TCSETA) && (cmd <= TCSETA + 2))
1185 {
1186 _termio_to_termios(args, &tmp);
1187 tio = &tmp;
1188 }
1189 else
1190 {
1191 tio = (struct termios*)args;
1192 }
1193
1194 if (tio == RT_NULL) return -RT_EINVAL;
1195
1196 config = serial->config;
1197 baudrate = _get_baudrate(cfgetospeed(tio));
1198 config.baud_rate = baudrate;
1199
1200 switch (tio->c_cflag & CSIZE)
1201 {
1202 case CS5:
1203 config.data_bits = DATA_BITS_5;
1204 break;
1205 case CS6:
1206 config.data_bits = DATA_BITS_6;
1207 break;
1208 case CS7:
1209 config.data_bits = DATA_BITS_7;
1210 break;
1211 default:
1212 config.data_bits = DATA_BITS_8;
1213 break;
1214 }
1215
1216 if (tio->c_cflag & CSTOPB) config.stop_bits = STOP_BITS_2;
1217 else config.stop_bits = STOP_BITS_1;
1218
1219 if (tio->c_cflag & PARENB)
1220 {
1221 if (tio->c_cflag & PARODD) config.parity = PARITY_ODD;
1222 else config.parity = PARITY_EVEN;
1223 }
1224 else config.parity = PARITY_NONE;
1225
1226 serial->ops->configure(serial, &config);
1227 }
1228 break;
1229 #ifndef RT_USING_TTY
1230 case TCFLSH:
1231 {
1232 int queue = (int)(rt_ubase_t)args;
1233
1234 _tc_flush(serial, queue);
1235 }
1236
1237 break;
1238 case TCXONC:
1239 break;
1240 #endif /*RT_USING_TTY*/
1241 #endif /*RT_USING_POSIX_TERMIOS*/
1242 case TIOCSWINSZ:
1243 {
1244 struct winsize* p_winsize;
1245
1246 p_winsize = (struct winsize*)args;
1247 rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row);
1248 }
1249 break;
1250 case TIOCGWINSZ:
1251 {
1252 struct winsize* p_winsize;
1253 p_winsize = (struct winsize*)args;
1254
1255 if(rt_thread_self() != rt_thread_find("tshell"))
1256 {
1257 /* only can be used in tshell thread; otherwise, return default size */
1258 p_winsize->ws_col = 80;
1259 p_winsize->ws_row = 24;
1260 }
1261 else
1262 {
1263 #include <shell.h>
1264 #define _TIO_BUFLEN 20
1265 char _tio_buf[_TIO_BUFLEN];
1266 unsigned char cnt1, cnt2, cnt3, i;
1267 char row_s[4], col_s[4];
1268 char *p;
1269
1270 rt_memset(_tio_buf, 0, _TIO_BUFLEN);
1271
1272 /* send the command to terminal for getting the window size of the terminal */
1273 rt_kprintf("\033[18t");
1274
1275 /* waiting for the response from the terminal */
1276 i = 0;
1277 while(i < _TIO_BUFLEN)
1278 {
1279 _tio_buf[i] = finsh_getchar();
1280 if(_tio_buf[i] != 't')
1281 {
1282 i ++;
1283 }
1284 else
1285 {
1286 break;
1287 }
1288 }
1289 if(i == _TIO_BUFLEN)
1290 {
1291 /* buffer overloaded, and return default size */
1292 p_winsize->ws_col = 80;
1293 p_winsize->ws_row = 24;
1294 break;
1295 }
1296
1297 /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */
1298 rt_memset(row_s,0,4);
1299 rt_memset(col_s,0,4);
1300 cnt1 = 0;
1301 while(cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';')
1302 {
1303 cnt1++;
1304 }
1305 cnt2 = ++cnt1;
1306 while(cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';')
1307 {
1308 cnt2++;
1309 }
1310 p = row_s;
1311 while(cnt1 < cnt2)
1312 {
1313 *p++ = _tio_buf[cnt1++];
1314 }
1315 p = col_s;
1316 cnt2++;
1317 cnt3 = rt_strlen(_tio_buf) - 1;
1318 while(cnt2 < cnt3)
1319 {
1320 *p++ = _tio_buf[cnt2++];
1321 }
1322
1323 /* load the window size date */
1324 p_winsize->ws_col = atoi(col_s);
1325 p_winsize->ws_row = atoi(row_s);
1326 #undef _TIO_BUFLEN
1327 }
1328
1329 p_winsize->ws_xpixel = 0;/* unused */
1330 p_winsize->ws_ypixel = 0;/* unused */
1331 }
1332 break;
1333 case FIONREAD:
1334 {
1335 rt_size_t recved = 0;
1336 rt_base_t level;
1337
1338 level = rt_spin_lock_irqsave(&(serial->spinlock));
1339 recved = _serial_fifo_calc_recved_len(serial);
1340 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
1341
1342 *(rt_size_t *)args = recved;
1343 }
1344 break;
1345 #endif /* RT_USING_POSIX_STDIO */
1346 default :
1347 /* control device */
1348 ret = serial->ops->control(serial, cmd, args);
1349 break;
1350 }
1351
1352 return ret;
1353 }
1354
1355 #ifdef RT_USING_DEVICE_OPS
1356 const static struct rt_device_ops serial_ops =
1357 {
1358 rt_serial_init,
1359 rt_serial_open,
1360 rt_serial_close,
1361 rt_serial_read,
1362 rt_serial_write,
1363 rt_serial_control
1364 };
1365 #endif
1366
1367 /*
1368 * serial register
1369 */
rt_hw_serial_register(struct rt_serial_device * serial,const char * name,rt_uint32_t flag,void * data)1370 rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
1371 const char *name,
1372 rt_uint32_t flag,
1373 void *data)
1374 {
1375 rt_err_t ret;
1376 struct rt_device *device;
1377 RT_ASSERT(serial != RT_NULL);
1378
1379 rt_spin_lock_init(&(serial->spinlock));
1380
1381 device = &(serial->parent);
1382
1383 device->type = RT_Device_Class_Char;
1384 device->rx_indicate = RT_NULL;
1385 device->tx_complete = RT_NULL;
1386
1387 #ifdef RT_USING_DEVICE_OPS
1388 device->ops = &serial_ops;
1389 #else
1390 device->init = rt_serial_init;
1391 device->open = rt_serial_open;
1392 device->close = rt_serial_close;
1393 device->read = rt_serial_read;
1394 device->write = rt_serial_write;
1395 device->control = rt_serial_control;
1396 #endif
1397 device->user_data = data;
1398
1399 /* register a character device */
1400 ret = rt_device_register(device, name, flag);
1401
1402 #ifdef RT_USING_POSIX_STDIO
1403 /* set fops */
1404 device->fops = &_serial_fops;
1405 #endif
1406
1407 #if defined(RT_USING_SMART)
1408 rt_hw_serial_register_tty(serial);
1409 #endif
1410
1411 return ret;
1412 }
1413
1414 /* ISR for serial interrupt */
rt_hw_serial_isr(struct rt_serial_device * serial,int event)1415 void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
1416 {
1417 switch (event & 0xff)
1418 {
1419 case RT_SERIAL_EVENT_RX_IND:
1420 {
1421 int ch = -1;
1422 rt_base_t level;
1423 struct rt_serial_rx_fifo* rx_fifo;
1424
1425 /* interrupt mode receive */
1426 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
1427 RT_ASSERT(rx_fifo != RT_NULL);
1428
1429 while (1)
1430 {
1431 ch = serial->ops->getc(serial);
1432 if (ch == -1) break;
1433
1434 /* disable interrupt */
1435 #ifdef RT_USING_SERIAL_BYPASS
1436 if (serial->bypass && serial->bypass->upper_h && (serial->bypass->upper_h->head.next != &serial->bypass->upper_h->head))
1437 {
1438 rt_bool_t skip = RT_FALSE;
1439 char buf = (char)ch;
1440 int ret;
1441 rt_list_t* node = serial->bypass->upper_h->head.next;
1442 do {
1443 struct rt_serial_bypass_func* bypass_run = rt_container_of(node, struct rt_serial_bypass_func, node);
1444 ret = bypass_run->bypass(serial, buf, bypass_run->data);
1445 if (!ret)
1446 {
1447 skip = RT_TRUE;
1448 break;
1449 }
1450 node = node->next;
1451 } while (node != &serial->bypass->upper_h->head);
1452
1453 if (skip)
1454 continue;
1455 }
1456
1457 #endif
1458 level = rt_spin_lock_irqsave(&(serial->spinlock));
1459 rx_fifo->buffer[rx_fifo->put_index] = ch;
1460 rx_fifo->put_index += 1;
1461 if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
1462
1463 /* if the next position is read index, discard this 'read char' */
1464 if (rx_fifo->put_index == rx_fifo->get_index)
1465 {
1466 rx_fifo->get_index = rx_fifo->put_index;
1467 rx_fifo->is_full = RT_TRUE;
1468
1469 _serial_check_buffer_size();
1470 }
1471
1472 /* enable interrupt */
1473 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
1474 }
1475
1476 #ifdef RT_USING_SERIAL_BYPASS
1477 if (serial->bypass && serial->bypass->lower_h)
1478 rt_workqueue_dowork(serial->bypass->lower_workq, &serial->bypass->work);
1479 #endif
1480
1481 if (serial->parent.rx_indicate != RT_NULL)
1482 {
1483 rt_size_t rx_length;
1484
1485 /* get rx length */
1486 level = rt_spin_lock_irqsave(&(serial->spinlock));
1487 rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
1488 (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
1489 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
1490
1491 if (rx_length)
1492 {
1493 serial->parent.rx_indicate(&serial->parent, rx_length);
1494 }
1495 }
1496 break;
1497 }
1498 case RT_SERIAL_EVENT_TX_DONE:
1499 {
1500 struct rt_serial_tx_fifo* tx_fifo;
1501
1502 tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
1503 rt_completion_done(&(tx_fifo->completion));
1504 break;
1505 }
1506 #ifdef RT_SERIAL_USING_DMA
1507 case RT_SERIAL_EVENT_TX_DMADONE:
1508 {
1509 const void *data_ptr;
1510 rt_size_t data_size;
1511 const void *last_data_ptr;
1512 struct rt_serial_tx_dma *tx_dma;
1513
1514 tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
1515
1516 rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
1517 if (rt_data_queue_peek(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
1518 {
1519 /* transmit next data node */
1520 tx_dma->activated = RT_TRUE;
1521 serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX);
1522 }
1523 else
1524 {
1525 tx_dma->activated = RT_FALSE;
1526 }
1527
1528 /* invoke callback */
1529 if (serial->parent.tx_complete != RT_NULL)
1530 {
1531 serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr);
1532 }
1533 break;
1534 }
1535 case RT_SERIAL_EVENT_RX_DMADONE:
1536 {
1537 int length;
1538 rt_base_t level;
1539
1540 /* get DMA rx length */
1541 length = (event & (~0xff)) >> 8;
1542
1543 if (serial->config.bufsz == 0)
1544 {
1545 struct rt_serial_rx_dma* rx_dma;
1546
1547 rx_dma = (struct rt_serial_rx_dma*) serial->serial_rx;
1548 RT_ASSERT(rx_dma != RT_NULL);
1549
1550 RT_ASSERT(serial->parent.rx_indicate != RT_NULL);
1551 serial->parent.rx_indicate(&(serial->parent), length);
1552 rx_dma->activated = RT_FALSE;
1553 }
1554 else
1555 {
1556 /* disable interrupt */
1557 level = rt_spin_lock_irqsave(&(serial->spinlock));
1558 /* update fifo put index */
1559 rt_dma_recv_update_put_index(serial, length);
1560 /* calculate received total length */
1561 length = rt_dma_calc_recved_len(serial);
1562 /* enable interrupt */
1563 rt_spin_unlock_irqrestore(&(serial->spinlock), level);
1564 /* invoke callback */
1565 if (serial->parent.rx_indicate != RT_NULL)
1566 {
1567 serial->parent.rx_indicate(&(serial->parent), length);
1568 }
1569 }
1570 break;
1571 }
1572 #endif /* RT_SERIAL_USING_DMA */
1573 }
1574 }
1575