1 /*
2 * Copyright (c) 2006-2018, 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 */
26
27 #include <rthw.h>
28 #include <rtthread.h>
29 #include <rtdevice.h>
30
31 // #define DEBUG_ENABLE
32 #define DEBUG_LEVEL DBG_LOG
33 #define DBG_SECTION_NAME "UART"
34 #define DEBUG_COLOR
35 #include <rtdbg.h>
36
37 #ifdef RT_USING_POSIX
38 #include <dfs_posix.h>
39 #include <dfs_poll.h>
40
41 #ifdef RT_USING_POSIX_TERMIOS
42 #include <posix_termios.h>
43 #endif
44
45 /* it's possible the 'getc/putc' is defined by stdio.h in gcc/newlib. */
46 #ifdef getc
47 #undef getc
48 #endif
49
50 #ifdef putc
51 #undef putc
52 #endif
53
serial_fops_rx_ind(rt_device_t dev,rt_size_t size)54 static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
55 {
56 rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
57
58 return RT_EOK;
59 }
60
61 /* fops for serial */
serial_fops_open(struct dfs_fd * fd)62 static int serial_fops_open(struct dfs_fd *fd)
63 {
64 rt_err_t ret = 0;
65 rt_uint16_t flags = 0;
66 rt_device_t device;
67
68 device = (rt_device_t)fd->data;
69 RT_ASSERT(device != RT_NULL);
70
71 switch (fd->flags & O_ACCMODE)
72 {
73 case O_RDONLY:
74 LOG_D("fops open: O_RDONLY!");
75 flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY;
76 break;
77 case O_WRONLY:
78 LOG_D("fops open: O_WRONLY!");
79 flags = RT_DEVICE_FLAG_WRONLY;
80 break;
81 case O_RDWR:
82 LOG_D("fops open: O_RDWR!");
83 flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR;
84 break;
85 default:
86 LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
87 break;
88 }
89
90 if ((fd->flags & O_ACCMODE) != O_WRONLY)
91 rt_device_set_rx_indicate(device, serial_fops_rx_ind);
92 ret = rt_device_open(device, flags);
93 if (ret == RT_EOK) return 0;
94
95 return ret;
96 }
97
serial_fops_close(struct dfs_fd * fd)98 static int serial_fops_close(struct dfs_fd *fd)
99 {
100 rt_device_t device;
101
102 device = (rt_device_t)fd->data;
103
104 rt_device_set_rx_indicate(device, RT_NULL);
105 rt_device_close(device);
106
107 return 0;
108 }
109
serial_fops_ioctl(struct dfs_fd * fd,int cmd,void * args)110 static int serial_fops_ioctl(struct dfs_fd *fd, int cmd, void *args)
111 {
112 rt_device_t device;
113
114 device = (rt_device_t)fd->data;
115 switch (cmd)
116 {
117 case FIONREAD:
118 break;
119 case FIONWRITE:
120 break;
121 }
122
123 return rt_device_control(device, cmd, args);
124 }
125
serial_fops_read(struct dfs_fd * fd,void * buf,size_t count)126 static int serial_fops_read(struct dfs_fd *fd, void *buf, size_t count)
127 {
128 int size = 0;
129 rt_device_t device;
130
131 device = (rt_device_t)fd->data;
132
133 do
134 {
135 size = rt_device_read(device, -1, buf, count);
136 if (size <= 0)
137 {
138 if (fd->flags & O_NONBLOCK)
139 {
140 size = -EAGAIN;
141 break;
142 }
143
144 rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER);
145 }
146 }while (size <= 0);
147
148 return size;
149 }
150
serial_fops_write(struct dfs_fd * fd,const void * buf,size_t count)151 static int serial_fops_write(struct dfs_fd *fd, const void *buf, size_t count)
152 {
153 rt_device_t device;
154
155 device = (rt_device_t)fd->data;
156 return rt_device_write(device, -1, buf, count);
157 }
158
serial_fops_poll(struct dfs_fd * fd,struct rt_pollreq * req)159 static int serial_fops_poll(struct dfs_fd *fd, struct rt_pollreq *req)
160 {
161 int mask = 0;
162 int flags = 0;
163 rt_device_t device;
164 struct rt_serial_device *serial;
165
166 device = (rt_device_t)fd->data;
167 RT_ASSERT(device != RT_NULL);
168
169 serial = (struct rt_serial_device *)device;
170
171 /* only support POLLIN */
172 flags = fd->flags & O_ACCMODE;
173 if (flags == O_RDONLY || flags == O_RDWR)
174 {
175 rt_base_t level;
176 struct rt_serial_rx_fifo* rx_fifo;
177
178 rt_poll_add(&(device->wait_queue), req);
179
180 rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
181
182 level = rt_hw_interrupt_disable();
183 if ((rx_fifo->get_index != rx_fifo->put_index) || (rx_fifo->get_index == rx_fifo->put_index && rx_fifo->is_full == RT_TRUE))
184 mask |= POLLIN;
185 rt_hw_interrupt_enable(level);
186 }
187
188 return mask;
189 }
190
191 const static struct dfs_file_ops _serial_fops =
192 {
193 serial_fops_open,
194 serial_fops_close,
195 serial_fops_ioctl,
196 serial_fops_read,
197 serial_fops_write,
198 RT_NULL, /* flush */
199 RT_NULL, /* lseek */
200 RT_NULL, /* getdents */
201 serial_fops_poll,
202 };
203 #endif
204
205 /*
206 * Serial poll routines
207 */
_serial_poll_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)208 rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
209 {
210 int ch;
211 int size;
212
213 RT_ASSERT(serial != RT_NULL);
214 size = length;
215
216 while (length)
217 {
218 ch = serial->ops->getc(serial);
219 if (ch == -1) break;
220
221 *data = ch;
222 data ++; length --;
223
224 if (ch == '\n') break;
225 }
226
227 return size - length;
228 }
229
_serial_poll_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)230 rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
231 {
232 int size;
233 RT_ASSERT(serial != RT_NULL);
234
235 size = length;
236 while (length)
237 {
238 /*
239 * to be polite with serial console add a line feed
240 * to the carriage return character
241 */
242 if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
243 {
244 serial->ops->putc(serial, '\r');
245 }
246
247 serial->ops->putc(serial, *data);
248
249 ++ data;
250 -- length;
251 }
252
253 return size - length;
254 }
255
256 /*
257 * Serial interrupt routines
258 */
_serial_int_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)259 rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
260 {
261 int size;
262 struct rt_serial_rx_fifo* rx_fifo;
263
264 RT_ASSERT(serial != RT_NULL);
265 size = length;
266
267 rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx;
268 RT_ASSERT(rx_fifo != RT_NULL);
269
270 /* read from software FIFO */
271 while (length)
272 {
273 int ch;
274 rt_base_t level;
275
276 /* disable interrupt */
277 level = rt_hw_interrupt_disable();
278
279 /* there's no data: */
280 if ((rx_fifo->get_index == rx_fifo->put_index) && (rx_fifo->is_full == RT_FALSE))
281 {
282 /* no data, enable interrupt and break out */
283 rt_hw_interrupt_enable(level);
284 break;
285 }
286
287 /* otherwise there's the data: */
288 ch = rx_fifo->buffer[rx_fifo->get_index];
289 rx_fifo->get_index += 1;
290 if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
291
292 if (rx_fifo->is_full == RT_TRUE)
293 {
294 rx_fifo->is_full = RT_FALSE;
295 }
296
297 /* enable interrupt */
298 rt_hw_interrupt_enable(level);
299
300 *data = ch & 0xff;
301 data ++; length --;
302 }
303
304 return size - length;
305 }
306
_serial_int_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)307 rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
308 {
309 int size;
310 struct rt_serial_tx_fifo *tx;
311
312 RT_ASSERT(serial != RT_NULL);
313
314 size = length;
315 tx = (struct rt_serial_tx_fifo*) serial->serial_tx;
316 RT_ASSERT(tx != RT_NULL);
317
318 while (length)
319 {
320 if (serial->ops->putc(serial, *(char*)data) == -1)
321 {
322 rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
323 continue;
324 }
325
326 data ++; length --;
327 }
328
329 return size - length;
330 }
331
332 #if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA)
_serial_fifo_calc_recved_len(struct rt_serial_device * serial)333 static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
334 {
335 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
336
337 RT_ASSERT(rx_fifo != RT_NULL);
338
339 if (rx_fifo->put_index == rx_fifo->get_index)
340 {
341 return (rx_fifo->is_full == RT_FALSE ? 0 : serial->config.bufsz);
342 }
343 else
344 {
345 if (rx_fifo->put_index > rx_fifo->get_index)
346 {
347 return rx_fifo->put_index - rx_fifo->get_index;
348 }
349 else
350 {
351 return serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index);
352 }
353 }
354 }
355 #endif /* RT_USING_POSIX || RT_SERIAL_USING_DMA */
356
357 #ifdef RT_SERIAL_USING_DMA
358 /**
359 * Calculate DMA received data length.
360 *
361 * @param serial serial device
362 *
363 * @return length
364 */
rt_dma_calc_recved_len(struct rt_serial_device * serial)365 static rt_size_t rt_dma_calc_recved_len(struct rt_serial_device *serial)
366 {
367 return _serial_fifo_calc_recved_len(serial);
368 }
369
370 /**
371 * Read data finish by DMA mode then update the get index for receive fifo.
372 *
373 * @param serial serial device
374 * @param len get data length for this operate
375 */
rt_dma_recv_update_get_index(struct rt_serial_device * serial,rt_size_t len)376 static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_size_t len)
377 {
378 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
379
380 RT_ASSERT(rx_fifo != RT_NULL);
381 RT_ASSERT(len <= rt_dma_calc_recved_len(serial));
382
383 if (rx_fifo->is_full && len != 0) rx_fifo->is_full = RT_FALSE;
384
385 rx_fifo->get_index += len;
386 if (rx_fifo->get_index >= serial->config.bufsz)
387 {
388 rx_fifo->get_index %= serial->config.bufsz;
389 }
390 }
391
392 /**
393 * DMA received finish then update put index for receive fifo.
394 *
395 * @param serial serial device
396 * @param len received length for this transmit
397 */
rt_dma_recv_update_put_index(struct rt_serial_device * serial,rt_size_t len)398 static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_size_t len)
399 {
400 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
401
402 RT_ASSERT(rx_fifo != RT_NULL);
403
404 if (rx_fifo->get_index <= rx_fifo->put_index)
405 {
406 rx_fifo->put_index += len;
407 /* beyond the fifo end */
408 if (rx_fifo->put_index >= serial->config.bufsz)
409 {
410 rx_fifo->put_index %= serial->config.bufsz;
411 /* force overwrite get index */
412 if (rx_fifo->put_index >= rx_fifo->get_index)
413 {
414 rx_fifo->is_full = RT_TRUE;
415 }
416 }
417 }
418 else
419 {
420 rx_fifo->put_index += len;
421 if (rx_fifo->put_index >= rx_fifo->get_index)
422 {
423 /* beyond the fifo end */
424 if (rx_fifo->put_index >= serial->config.bufsz)
425 {
426 rx_fifo->put_index %= serial->config.bufsz;
427 }
428 /* force overwrite get index */
429 rx_fifo->is_full = RT_TRUE;
430 }
431 }
432
433 if(rx_fifo->is_full == RT_TRUE)
434 {
435 rx_fifo->get_index = rx_fifo->put_index;
436 }
437
438 if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
439 }
440
441 /*
442 * Serial DMA routines
443 */
_serial_dma_rx(struct rt_serial_device * serial,rt_uint8_t * data,int length)444 rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)
445 {
446 rt_base_t level;
447
448 RT_ASSERT((serial != RT_NULL) && (data != RT_NULL));
449
450 level = rt_hw_interrupt_disable();
451
452 if (serial->config.bufsz == 0)
453 {
454 int result = RT_EOK;
455 struct rt_serial_rx_dma *rx_dma;
456
457 rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
458 RT_ASSERT(rx_dma != RT_NULL);
459
460 if (rx_dma->activated != RT_TRUE)
461 {
462 rx_dma->activated = RT_TRUE;
463 RT_ASSERT(serial->ops->dma_transmit != RT_NULL);
464 serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX);
465 }
466 else result = -RT_EBUSY;
467 rt_hw_interrupt_enable(level);
468
469 if (result == RT_EOK) return length;
470
471 rt_set_errno(result);
472 return 0;
473 }
474 else
475 {
476 struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
477 rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial);
478
479 RT_ASSERT(rx_fifo != RT_NULL);
480
481 if (length < fifo_recved_len)
482 recv_len = length;
483 else
484 recv_len = fifo_recved_len;
485
486 if (rx_fifo->get_index + recv_len < serial->config.bufsz)
487 rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len);
488 else
489 {
490 rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index,
491 serial->config.bufsz - rx_fifo->get_index);
492 rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer,
493 recv_len + rx_fifo->get_index - serial->config.bufsz);
494 }
495 rt_dma_recv_update_get_index(serial, recv_len);
496 rt_hw_interrupt_enable(level);
497 return recv_len;
498 }
499 }
500
_serial_dma_tx(struct rt_serial_device * serial,const rt_uint8_t * data,int length)501 rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)
502 {
503 rt_base_t level;
504 rt_err_t result;
505 struct rt_serial_tx_dma *tx_dma;
506
507 tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx);
508
509 result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER);
510 if (result == RT_EOK)
511 {
512 level = rt_hw_interrupt_disable();
513 if (tx_dma->activated != RT_TRUE)
514 {
515 tx_dma->activated = RT_TRUE;
516 rt_hw_interrupt_enable(level);
517
518 /* make a DMA transfer */
519 serial->ops->dma_transmit(serial, (rt_uint8_t *)data, length, RT_SERIAL_DMA_TX);
520 }
521 else
522 {
523 rt_hw_interrupt_enable(level);
524 }
525
526 return length;
527 }
528 else
529 {
530 rt_set_errno(result);
531 return 0;
532 }
533 }
534 #endif /* RT_SERIAL_USING_DMA */
535
536 /* RT-Thread Device Interface */
537 /*
538 * This function initializes serial device.
539 */
rt_serial_init(struct rt_device * dev)540 static rt_err_t rt_serial_init(struct rt_device *dev)
541 {
542 rt_err_t result = RT_EOK;
543 struct rt_serial_device *serial;
544
545 RT_ASSERT(dev != RT_NULL);
546 serial = (struct rt_serial_device *)dev;
547
548 /* initialize rx/tx */
549 serial->serial_rx = RT_NULL;
550 serial->serial_tx = RT_NULL;
551
552 /* apply configuration */
553 if (serial->ops->configure)
554 result = serial->ops->configure(serial, &serial->config);
555
556 return result;
557 }
558
rt_serial_open(struct rt_device * dev,rt_uint16_t oflag)559 static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
560 {
561 rt_uint16_t stream_flag = 0;
562 struct rt_serial_device *serial;
563
564 RT_ASSERT(dev != RT_NULL);
565 serial = (struct rt_serial_device *)dev;
566
567 LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
568 dev, oflag);
569 /* check device flag with the open flag */
570 if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
571 return -RT_EIO;
572 if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
573 return -RT_EIO;
574 if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
575 return -RT_EIO;
576 if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
577 return -RT_EIO;
578
579 /* keep steam flag */
580 if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM))
581 stream_flag = RT_DEVICE_FLAG_STREAM;
582
583 /* get open flags */
584 dev->open_flag = oflag & 0xff;
585
586 /* initialize the Rx/Tx structure according to open flag */
587 if (serial->serial_rx == RT_NULL)
588 {
589 if (oflag & RT_DEVICE_FLAG_INT_RX)
590 {
591 struct rt_serial_rx_fifo* rx_fifo;
592
593 rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
594 serial->config.bufsz);
595 RT_ASSERT(rx_fifo != RT_NULL);
596 rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
597 rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
598 rx_fifo->put_index = 0;
599 rx_fifo->get_index = 0;
600 rx_fifo->is_full = RT_FALSE;
601
602 serial->serial_rx = rx_fifo;
603 dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
604 /* configure low level device */
605 serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
606 }
607 #ifdef RT_SERIAL_USING_DMA
608 else if (oflag & RT_DEVICE_FLAG_DMA_RX)
609 {
610 if (serial->config.bufsz == 0) {
611 struct rt_serial_rx_dma* rx_dma;
612
613 rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma));
614 RT_ASSERT(rx_dma != RT_NULL);
615 rx_dma->activated = RT_FALSE;
616
617 serial->serial_rx = rx_dma;
618 } else {
619 struct rt_serial_rx_fifo* rx_fifo;
620
621 rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
622 serial->config.bufsz);
623 RT_ASSERT(rx_fifo != RT_NULL);
624 rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
625 rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
626 rx_fifo->put_index = 0;
627 rx_fifo->get_index = 0;
628 rx_fifo->is_full = RT_FALSE;
629 serial->serial_rx = rx_fifo;
630 /* configure fifo address and length to low level device */
631 serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX);
632 }
633 dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
634 }
635 #endif /* RT_SERIAL_USING_DMA */
636 else
637 {
638 serial->serial_rx = RT_NULL;
639 }
640 }
641 else
642 {
643 if (oflag & RT_DEVICE_FLAG_INT_RX)
644 dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
645 #ifdef RT_SERIAL_USING_DMA
646 else if (oflag & RT_DEVICE_FLAG_DMA_RX)
647 dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
648 #endif /* RT_SERIAL_USING_DMA */
649 }
650
651 if (serial->serial_tx == RT_NULL)
652 {
653 if (oflag & RT_DEVICE_FLAG_INT_TX)
654 {
655 struct rt_serial_tx_fifo *tx_fifo;
656
657 tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc(sizeof(struct rt_serial_tx_fifo));
658 RT_ASSERT(tx_fifo != RT_NULL);
659
660 rt_completion_init(&(tx_fifo->completion));
661 serial->serial_tx = tx_fifo;
662
663 dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
664 /* configure low level device */
665 serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
666 }
667 #ifdef RT_SERIAL_USING_DMA
668 else if (oflag & RT_DEVICE_FLAG_DMA_TX)
669 {
670 struct rt_serial_tx_dma* tx_dma;
671
672 tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
673 RT_ASSERT(tx_dma != RT_NULL);
674 tx_dma->activated = RT_FALSE;
675
676 rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
677 serial->serial_tx = tx_dma;
678
679 dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
680 }
681 #endif /* RT_SERIAL_USING_DMA */
682 else
683 {
684 serial->serial_tx = RT_NULL;
685 }
686 }
687 else
688 {
689 if (oflag & RT_DEVICE_FLAG_INT_TX)
690 dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
691 #ifdef RT_SERIAL_USING_DMA
692 else if (oflag & RT_DEVICE_FLAG_DMA_TX)
693 dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
694 #endif /* RT_SERIAL_USING_DMA */
695 }
696
697 /* set stream flag */
698 dev->open_flag |= stream_flag;
699
700 return RT_EOK;
701 }
702
rt_serial_close(struct rt_device * dev)703 static rt_err_t rt_serial_close(struct rt_device *dev)
704 {
705 struct rt_serial_device *serial;
706
707 RT_ASSERT(dev != RT_NULL);
708 serial = (struct rt_serial_device *)dev;
709
710 /* this device has more reference count */
711 if (dev->ref_count > 1) return RT_EOK;
712
713 if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
714 {
715 struct rt_serial_rx_fifo* rx_fifo;
716
717 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
718 RT_ASSERT(rx_fifo != RT_NULL);
719
720 rt_free(rx_fifo);
721 serial->serial_rx = RT_NULL;
722 dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
723 /* configure low level device */
724 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
725 }
726 #ifdef RT_SERIAL_USING_DMA
727 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
728 {
729 if (serial->config.bufsz == 0) {
730 struct rt_serial_rx_dma* rx_dma;
731
732 rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
733 RT_ASSERT(rx_dma != RT_NULL);
734
735 rt_free(rx_dma);
736 } else {
737 struct rt_serial_rx_fifo* rx_fifo;
738
739 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
740 RT_ASSERT(rx_fifo != RT_NULL);
741
742 rt_free(rx_fifo);
743 }
744 /* configure low level device */
745 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
746 serial->serial_rx = RT_NULL;
747 dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
748 }
749 #endif /* RT_SERIAL_USING_DMA */
750
751 if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
752 {
753 struct rt_serial_tx_fifo* tx_fifo;
754
755 tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
756 RT_ASSERT(tx_fifo != RT_NULL);
757
758 rt_free(tx_fifo);
759 serial->serial_tx = RT_NULL;
760 dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
761 /* configure low level device */
762 serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
763 }
764 #ifdef RT_SERIAL_USING_DMA
765 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
766 {
767 struct rt_serial_tx_dma* tx_dma;
768
769 tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx;
770 RT_ASSERT(tx_dma != RT_NULL);
771
772 rt_free(tx_dma);
773 serial->serial_tx = RT_NULL;
774 dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
775 }
776 #endif /* RT_SERIAL_USING_DMA */
777 return RT_EOK;
778 }
779
rt_serial_read(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)780 static rt_size_t rt_serial_read(struct rt_device *dev,
781 rt_off_t pos,
782 void *buffer,
783 rt_size_t size)
784 {
785 struct rt_serial_device *serial;
786
787 RT_ASSERT(dev != RT_NULL);
788 if (size == 0) return 0;
789
790 serial = (struct rt_serial_device *)dev;
791
792 if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
793 {
794 return _serial_int_rx(serial, buffer, size);
795 }
796 #ifdef RT_SERIAL_USING_DMA
797 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
798 {
799 return _serial_dma_rx(serial, buffer, size);
800 }
801 #endif /* RT_SERIAL_USING_DMA */
802
803 return _serial_poll_rx(serial, buffer, size);
804 }
805
rt_serial_write(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)806 static rt_size_t rt_serial_write(struct rt_device *dev,
807 rt_off_t pos,
808 const void *buffer,
809 rt_size_t size)
810 {
811 struct rt_serial_device *serial;
812
813 RT_ASSERT(dev != RT_NULL);
814 if (size == 0) return 0;
815
816 serial = (struct rt_serial_device *)dev;
817
818 if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
819 {
820 return _serial_int_tx(serial, buffer, size);
821 }
822 #ifdef RT_SERIAL_USING_DMA
823 else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
824 {
825 return _serial_dma_tx(serial, buffer, size);
826 }
827 #endif /* RT_SERIAL_USING_DMA */
828 else
829 {
830 return _serial_poll_tx(serial, buffer, size);
831 }
832 }
833
834 #ifdef RT_USING_POSIX_TERMIOS
835 struct speed_baudrate_item
836 {
837 speed_t speed;
838 int baudrate;
839 };
840
841 const static struct speed_baudrate_item _tbl[] =
842 {
843 {B2400, BAUD_RATE_2400},
844 {B4800, BAUD_RATE_4800},
845 {B9600, BAUD_RATE_9600},
846 {B19200, BAUD_RATE_19200},
847 {B38400, BAUD_RATE_38400},
848 {B57600, BAUD_RATE_57600},
849 {B115200, BAUD_RATE_115200},
850 {B230400, BAUD_RATE_230400},
851 {B460800, BAUD_RATE_460800},
852 {B921600, BAUD_RATE_921600},
853 {B2000000, BAUD_RATE_2000000},
854 {B3000000, BAUD_RATE_3000000},
855 };
856
_get_speed(int baudrate)857 static speed_t _get_speed(int baudrate)
858 {
859 int index;
860
861 for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++)
862 {
863 if (_tbl[index].baudrate == baudrate)
864 return _tbl[index].speed;
865 }
866
867 return B0;
868 }
869
_get_baudrate(speed_t speed)870 static int _get_baudrate(speed_t speed)
871 {
872 int index;
873
874 for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++)
875 {
876 if (_tbl[index].speed == speed)
877 return _tbl[index].baudrate;
878 }
879
880 return 0;
881 }
882
_tc_flush(struct rt_serial_device * serial,int queue)883 static void _tc_flush(struct rt_serial_device *serial, int queue)
884 {
885 int ch = -1;
886 struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
887 struct rt_device *device = RT_NULL;
888
889 RT_ASSERT(serial != RT_NULL);
890
891 device = &(serial->parent);
892 rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
893
894 switch(queue)
895 {
896 case TCIFLUSH:
897 case TCIOFLUSH:
898
899 RT_ASSERT(rx_fifo != RT_NULL);
900
901 if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX))
902 {
903 RT_ASSERT(RT_NULL != rx_fifo);
904 rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
905 rx_fifo->put_index = 0;
906 rx_fifo->get_index = 0;
907 rx_fifo->is_full = RT_FALSE;
908 }
909 else
910 {
911 while (1)
912 {
913 ch = serial->ops->getc(serial);
914 if (ch == -1) break;
915 }
916 }
917
918 break;
919
920 case TCOFLUSH:
921 break;
922 }
923
924 }
925
926 #endif
927
rt_serial_control(struct rt_device * dev,int cmd,void * args)928 static rt_err_t rt_serial_control(struct rt_device *dev,
929 int cmd,
930 void *args)
931 {
932 rt_err_t ret = RT_EOK;
933 struct rt_serial_device *serial;
934
935 RT_ASSERT(dev != RT_NULL);
936 serial = (struct rt_serial_device *)dev;
937
938 switch (cmd)
939 {
940 case RT_DEVICE_CTRL_SUSPEND:
941 /* suspend device */
942 dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
943 break;
944
945 case RT_DEVICE_CTRL_RESUME:
946 /* resume device */
947 dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
948 break;
949
950 case RT_DEVICE_CTRL_CONFIG:
951 if (args)
952 {
953 struct serial_configure *pconfig = (struct serial_configure *) args;
954 if (pconfig->bufsz != serial->config.bufsz && serial->parent.ref_count)
955 {
956 /*can not change buffer size*/
957 return RT_EBUSY;
958 }
959 /* set serial configure */
960 serial->config = *pconfig;
961 if (serial->parent.ref_count)
962 {
963 /* serial device has been opened, to configure it */
964 serial->ops->configure(serial, (struct serial_configure *) args);
965 }
966 }
967
968 break;
969
970 #ifdef RT_USING_POSIX_TERMIOS
971 case TCGETA:
972 {
973 struct termios *tio = (struct termios*)args;
974 if (tio == RT_NULL) return -RT_EINVAL;
975
976 tio->c_iflag = 0;
977 tio->c_oflag = 0;
978 tio->c_lflag = 0;
979
980 /* update oflag for console device */
981 if (rt_console_get_device() == dev)
982 tio->c_oflag = OPOST | ONLCR;
983
984 /* set cflag */
985 tio->c_cflag = 0;
986 if (serial->config.data_bits == DATA_BITS_5)
987 tio->c_cflag = CS5;
988 else if (serial->config.data_bits == DATA_BITS_6)
989 tio->c_cflag = CS6;
990 else if (serial->config.data_bits == DATA_BITS_7)
991 tio->c_cflag = CS7;
992 else if (serial->config.data_bits == DATA_BITS_8)
993 tio->c_cflag = CS8;
994
995 if (serial->config.stop_bits == STOP_BITS_2)
996 tio->c_cflag |= CSTOPB;
997
998 if (serial->config.parity == PARITY_EVEN)
999 tio->c_cflag |= PARENB;
1000 else if (serial->config.parity == PARITY_ODD)
1001 tio->c_cflag |= (PARODD | PARENB);
1002
1003 cfsetospeed(tio, _get_speed(serial->config.baud_rate));
1004 }
1005 break;
1006
1007 case TCSETAW:
1008 case TCSETAF:
1009 case TCSETA:
1010 {
1011 int baudrate;
1012 struct serial_configure config;
1013
1014 struct termios *tio = (struct termios*)args;
1015 if (tio == RT_NULL) return -RT_EINVAL;
1016
1017 config = serial->config;
1018
1019 baudrate = _get_baudrate(cfgetospeed(tio));
1020 config.baud_rate = baudrate;
1021
1022 switch (tio->c_cflag & CSIZE)
1023 {
1024 case CS5:
1025 config.data_bits = DATA_BITS_5;
1026 break;
1027 case CS6:
1028 config.data_bits = DATA_BITS_6;
1029 break;
1030 case CS7:
1031 config.data_bits = DATA_BITS_7;
1032 break;
1033 default:
1034 config.data_bits = DATA_BITS_8;
1035 break;
1036 }
1037
1038 if (tio->c_cflag & CSTOPB) config.stop_bits = STOP_BITS_2;
1039 else config.stop_bits = STOP_BITS_1;
1040
1041 if (tio->c_cflag & PARENB)
1042 {
1043 if (tio->c_cflag & PARODD) config.parity = PARITY_ODD;
1044 else config.parity = PARITY_EVEN;
1045 }
1046 else config.parity = PARITY_NONE;
1047
1048 serial->ops->configure(serial, &config);
1049 }
1050 break;
1051 case TCFLSH:
1052 {
1053 int queue = (int)args;
1054
1055 _tc_flush(serial, queue);
1056 }
1057
1058 break;
1059 case TCXONC:
1060 break;
1061 #endif
1062 #ifdef RT_USING_POSIX
1063 case FIONREAD:
1064 {
1065 rt_size_t recved = 0;
1066 rt_base_t level;
1067
1068 level = rt_hw_interrupt_disable();
1069 recved = _serial_fifo_calc_recved_len(serial);
1070 rt_hw_interrupt_enable(level);
1071
1072 *(rt_size_t *)args = recved;
1073 }
1074 break;
1075 #endif
1076 default :
1077 /* control device */
1078 ret = serial->ops->control(serial, cmd, args);
1079 break;
1080 }
1081
1082 return ret;
1083 }
1084
1085 #ifdef RT_USING_DEVICE_OPS
1086 const static struct rt_device_ops serial_ops =
1087 {
1088 rt_serial_init,
1089 rt_serial_open,
1090 rt_serial_close,
1091 rt_serial_read,
1092 rt_serial_write,
1093 rt_serial_control
1094 };
1095 #endif
1096
1097 /*
1098 * serial register
1099 */
rt_hw_serial_register(struct rt_serial_device * serial,const char * name,rt_uint32_t flag,void * data)1100 rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
1101 const char *name,
1102 rt_uint32_t flag,
1103 void *data)
1104 {
1105 rt_err_t ret;
1106 struct rt_device *device;
1107 RT_ASSERT(serial != RT_NULL);
1108
1109 device = &(serial->parent);
1110
1111 device->type = RT_Device_Class_Char;
1112 device->rx_indicate = RT_NULL;
1113 device->tx_complete = RT_NULL;
1114
1115 #ifdef RT_USING_DEVICE_OPS
1116 device->ops = &serial_ops;
1117 #else
1118 device->init = rt_serial_init;
1119 device->open = rt_serial_open;
1120 device->close = rt_serial_close;
1121 device->read = rt_serial_read;
1122 device->write = rt_serial_write;
1123 device->control = rt_serial_control;
1124 #endif
1125 device->user_data = data;
1126
1127 /* register a character device */
1128 ret = rt_device_register(device, name, flag);
1129
1130 #if defined(RT_USING_POSIX)
1131 /* set fops */
1132 device->fops = &_serial_fops;
1133 #endif
1134
1135 return ret;
1136 }
1137
1138 /* ISR for serial interrupt */
rt_hw_serial_isr(struct rt_serial_device * serial,int event)1139 void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
1140 {
1141 switch (event & 0xff)
1142 {
1143 case RT_SERIAL_EVENT_RX_IND:
1144 {
1145 int ch = -1;
1146 rt_base_t level;
1147 struct rt_serial_rx_fifo* rx_fifo;
1148
1149 /* interrupt mode receive */
1150 rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
1151 RT_ASSERT(rx_fifo != RT_NULL);
1152
1153 while (1)
1154 {
1155 ch = serial->ops->getc(serial);
1156 if (ch == -1) break;
1157
1158
1159 /* disable interrupt */
1160 level = rt_hw_interrupt_disable();
1161
1162 rx_fifo->buffer[rx_fifo->put_index] = ch;
1163 rx_fifo->put_index += 1;
1164 if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;
1165
1166 /* if the next position is read index, discard this 'read char' */
1167 if (rx_fifo->put_index == rx_fifo->get_index)
1168 {
1169 rx_fifo->get_index += 1;
1170 rx_fifo->is_full = RT_TRUE;
1171 if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
1172 }
1173
1174 /* enable interrupt */
1175 rt_hw_interrupt_enable(level);
1176 }
1177
1178 /* invoke callback */
1179 if (serial->parent.rx_indicate != RT_NULL)
1180 {
1181 rt_size_t rx_length;
1182
1183 /* get rx length */
1184 level = rt_hw_interrupt_disable();
1185 rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):
1186 (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
1187 rt_hw_interrupt_enable(level);
1188
1189 if (rx_length)
1190 {
1191 serial->parent.rx_indicate(&serial->parent, rx_length);
1192 }
1193 }
1194 break;
1195 }
1196 case RT_SERIAL_EVENT_TX_DONE:
1197 {
1198 struct rt_serial_tx_fifo* tx_fifo;
1199
1200 tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
1201 rt_completion_done(&(tx_fifo->completion));
1202 break;
1203 }
1204 #ifdef RT_SERIAL_USING_DMA
1205 case RT_SERIAL_EVENT_TX_DMADONE:
1206 {
1207 const void *data_ptr;
1208 rt_size_t data_size;
1209 const void *last_data_ptr;
1210 struct rt_serial_tx_dma *tx_dma;
1211
1212 tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
1213
1214 rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
1215 if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
1216 {
1217 /* transmit next data node */
1218 tx_dma->activated = RT_TRUE;
1219 serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX);
1220 }
1221 else
1222 {
1223 tx_dma->activated = RT_FALSE;
1224 }
1225
1226 /* invoke callback */
1227 if (serial->parent.tx_complete != RT_NULL)
1228 {
1229 serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr);
1230 }
1231 break;
1232 }
1233 case RT_SERIAL_EVENT_RX_DMADONE:
1234 {
1235 int length;
1236 rt_base_t level;
1237
1238 /* get DMA rx length */
1239 length = (event & (~0xff)) >> 8;
1240
1241 if (serial->config.bufsz == 0)
1242 {
1243 struct rt_serial_rx_dma* rx_dma;
1244
1245 rx_dma = (struct rt_serial_rx_dma*) serial->serial_rx;
1246 RT_ASSERT(rx_dma != RT_NULL);
1247
1248 RT_ASSERT(serial->parent.rx_indicate != RT_NULL);
1249 serial->parent.rx_indicate(&(serial->parent), length);
1250 rx_dma->activated = RT_FALSE;
1251 }
1252 else
1253 {
1254 /* disable interrupt */
1255 level = rt_hw_interrupt_disable();
1256 /* update fifo put index */
1257 rt_dma_recv_update_put_index(serial, length);
1258 /* calculate received total length */
1259 length = rt_dma_calc_recved_len(serial);
1260 /* enable interrupt */
1261 rt_hw_interrupt_enable(level);
1262 /* invoke callback */
1263 if (serial->parent.rx_indicate != RT_NULL)
1264 {
1265 serial->parent.rx_indicate(&(serial->parent), length);
1266 }
1267 }
1268 break;
1269 }
1270 #endif /* RT_SERIAL_USING_DMA */
1271 }
1272 }
1273
1274