xref: /nrf52832-nimble/rt-thread/components/drivers/serial/serial.c (revision 104654410c56c573564690304ae786df310c91fc)
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