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  * 2021-06-01     KyleChan     first version
9  */
10 
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 
15 #define DBG_TAG "Serial"
16 #define DBG_LVL DBG_INFO
17 #include <rtdbg.h>
18 
19 #ifdef RT_SERIAL_BUF_STRATEGY_DROP
20 #define RT_SERIAL_FIFO_LOCK(spinlock) ((rt_base_t)0)
21 #define RT_SERIAL_FIFO_UNLOCK(spinlock, level) \
22     do {                                       \
23         RT_UNUSED(spinlock);                   \
24         RT_UNUSED(level);                      \
25     } while (0)
26 #else
27 #define RT_SERIAL_FIFO_LOCK(spinlock)          rt_spin_lock_irqsave(spinlock)
28 #define RT_SERIAL_FIFO_UNLOCK(spinlock, level) rt_spin_unlock_irqrestore(spinlock, level)
29 #endif /* RT_SERIAL_BUF_STRATEGY_DROP */
30 
31 #ifdef RT_USING_POSIX_STDIO
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <poll.h>
35 #include <sys/ioctl.h>
36 #include <dfs_file.h>
37 
38 #ifdef RT_USING_POSIX_TERMIOS
39 #include <termios.h>
40 #endif
41 
42 #ifdef getc
43 #undef getc
44 #endif
45 
46 #ifdef putc
47 #undef putc
48 #endif
49 
50 RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind);
51 
serial_fops_rx_ind(rt_device_t dev,rt_size_t size)52 static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
53 {
54     rt_wqueue_wakeup(&dev->wait_queue, (void *)POLLIN);
55 
56     RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size));
57 
58     return RT_EOK;
59 }
60 
61 /* fops for serial */
serial_fops_open(struct dfs_file * fd)62 static int serial_fops_open(struct dfs_file *fd)
63 {
64     rt_err_t                 ret   = 0;
65     rt_uint16_t              flags = 0;
66     rt_device_t              device;
67     struct rt_serial_device *serial;
68 
69     device = (rt_device_t)fd->vnode->data;
70     RT_ASSERT(device != RT_NULL);
71 
72     switch (fd->flags & O_ACCMODE)
73     {
74     case O_RDONLY:
75         LOG_D("fops open: O_RDONLY!");
76         flags = RT_DEVICE_FLAG_RDONLY;
77         break;
78     case O_WRONLY:
79         LOG_D("fops open: O_WRONLY!");
80         flags = RT_DEVICE_FLAG_WRONLY;
81         break;
82     case O_RDWR:
83         LOG_D("fops open: O_RDWR!");
84         flags = RT_DEVICE_FLAG_RDWR;
85         break;
86     default:
87         LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
88         break;
89     }
90 
91     if ((fd->flags & O_ACCMODE) != O_WRONLY)
92         rt_device_set_rx_indicate(device, serial_fops_rx_ind);
93 
94     rt_device_close(device);
95     ret = rt_device_open(device, flags | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING);
96     if (ret == RT_EOK)
97     {
98         serial                = (struct rt_serial_device *)device;
99         serial->is_posix_mode = RT_TRUE;
100     }
101 
102     return ret;
103 }
104 
serial_fops_close(struct dfs_file * fd)105 static int serial_fops_close(struct dfs_file *fd)
106 {
107     rt_device_t device;
108 
109     device = (rt_device_t)fd->vnode->data;
110 
111     rt_device_set_rx_indicate(device, RT_NULL);
112     rt_device_close(device);
113 
114     return 0;
115 }
116 
serial_fops_ioctl(struct dfs_file * fd,int cmd,void * args)117 static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
118 {
119     rt_device_t device;
120     int         flags = (int)(rt_base_t)args;
121     int         mask  = O_NONBLOCK | O_APPEND;
122 
123     device = (rt_device_t)fd->vnode->data;
124     switch (cmd)
125     {
126     case FIONREAD:
127         break;
128     case FIONWRITE:
129         break;
130     case F_SETFL:
131         flags     &= mask;
132         fd->flags &= ~mask;
133         fd->flags |= flags;
134         break;
135     default:
136         break;
137     }
138 
139     return rt_device_control(device, cmd, args);
140 }
141 
142 #ifdef RT_USING_DFS_V2
serial_fops_read(struct dfs_file * fd,void * buf,size_t count,off_t * pos)143 static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos)
144 #else
145 static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
146 #endif
147 {
148     ssize_t     size = 0;
149     rt_device_t device;
150     rt_int32_t  rx_timout;
151 
152     if (count == 0) return 0;
153     RT_ASSERT(fd != RT_NULL && buf != RT_NULL);
154 
155     device = (rt_device_t)fd->vnode->data;
156     RT_ASSERT(device != RT_NULL);
157 
158     /* nonblock mode */
159     if (fd->flags & O_NONBLOCK)
160     {
161         rx_timout = RT_WAITING_NO;
162         rt_device_control(device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timout);
163         size = rt_device_read(device, -1, buf, count);
164         if (size <= 0)
165         {
166             size = -1;
167             rt_set_errno(EAGAIN);
168         }
169     }
170     else
171     {
172         rx_timout = RT_WAITING_FOREVER;
173         rt_device_control(device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timout);
174         size = rt_device_read(device, -1, buf, count);
175     }
176 
177 
178     return size;
179 }
180 
181 #ifdef RT_USING_DFS_V2
serial_fops_write(struct dfs_file * fd,const void * buf,size_t count,off_t * pos)182 static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos)
183 #else
184 static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
185 #endif
186 {
187     ssize_t     size = 0;
188     rt_device_t device;
189     rt_int32_t  tx_timeout;
190 
191     device = (rt_device_t)fd->vnode->data;
192 
193     if (fd->flags & O_NONBLOCK)
194     {
195         tx_timeout = RT_WAITING_NO;
196         rt_device_control(device, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
197         size = rt_device_write(device, -1, buf, count);
198         if (size <= 0)
199         {
200             size = -1;
201             rt_set_errno(EAGAIN);
202         }
203     }
204     else
205     {
206         tx_timeout = RT_WAITING_FOREVER;
207         rt_device_control(device, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
208         size = rt_device_write(device, -1, buf, count);
209     }
210 
211     return size;
212 }
213 
serial_fops_flush(struct dfs_file * fd)214 static int serial_fops_flush(struct dfs_file *fd)
215 {
216     rt_device_t device;
217     device = (rt_device_t)fd->vnode->data;
218     RT_ASSERT(device != RT_NULL);
219 
220     rt_device_control(device, RT_SERIAL_CTRL_TX_FLUSH, (void *)RT_NULL);
221     rt_device_control(device, RT_SERIAL_CTRL_RX_FLUSH, (void *)RT_NULL);
222 
223     return 0;
224 }
225 
serial_fops_poll(struct dfs_file * fd,struct rt_pollreq * req)226 static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
227 {
228     int                      mask  = 0;
229     int                      flags = 0;
230     rt_device_t              device;
231     struct rt_serial_device *serial;
232 
233     device = (rt_device_t)fd->vnode->data;
234     RT_ASSERT(device != RT_NULL);
235 
236     serial = (struct rt_serial_device *)device;
237 
238     /* only support POLLIN */
239     flags = fd->flags & O_ACCMODE;
240     if (flags == O_RDONLY || flags == O_RDWR)
241     {
242         rt_base_t                 level;
243         struct rt_serial_rx_fifo *rx_fifo;
244 
245         rt_poll_add(&device->wait_queue, req);
246 
247         rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
248 
249         level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
250         if (rt_ringbuffer_data_len(&rx_fifo->rb))
251             mask |= POLLIN;
252         RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
253     }
254     /* mask|=POLLOUT; */
255     return mask;
256 }
257 
258 const static struct dfs_file_ops _serial_fops =
259     {
260         .open  = serial_fops_open,
261         .close = serial_fops_close,
262         .ioctl = serial_fops_ioctl,
263         .read  = serial_fops_read,
264         .write = serial_fops_write,
265         .flush = serial_fops_flush,
266         .poll  = serial_fops_poll,
267 };
268 #endif /* RT_USING_POSIX_STDIO */
269 
rt_serial_get_linear_buffer(struct rt_ringbuffer * rb,rt_uint8_t ** ptr)270 static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb,
271                                               rt_uint8_t          **ptr)
272 {
273     rt_size_t size;
274 
275     RT_ASSERT(rb != RT_NULL);
276 
277     /* whether has enough data  */
278     size = rt_ringbuffer_data_len(rb);
279 
280     /* no data */
281     if (size == 0)
282         return 0;
283 
284     *ptr = &rb->buffer_ptr[rb->read_index];
285 
286     if (rb->buffer_size - rb->read_index > size)
287     {
288         return size;
289     }
290 
291     return rb->buffer_size - rb->read_index;
292 }
293 
294 #ifdef RT_SERIAL_USING_DMA
rt_serial_update_read_index(struct rt_ringbuffer * rb,rt_uint16_t length)295 static void rt_serial_update_read_index(struct rt_ringbuffer *rb,
296                                         rt_uint16_t           length)
297 {
298     rt_size_t size;
299 
300     RT_ASSERT(rb != RT_NULL);
301 
302     /* whether has enough data  */
303     size = rt_ringbuffer_data_len(rb);
304 
305     /* no data */
306     if (size == 0)
307         return;
308 
309     /* less data */
310     if (size < length)
311         length = size;
312 
313     if (rb->buffer_size - rb->read_index > length)
314     {
315         rb->read_index += length;
316         return;
317     }
318 
319     /* we are going into the other side of the mirror */
320     rb->read_mirror = ~rb->read_mirror;
321     rb->read_index  = length - (rb->buffer_size - rb->read_index);
322 
323     return;
324 }
325 
rt_serial_update_write_index(struct rt_ringbuffer * rb,rt_uint16_t length)326 static void rt_serial_update_write_index(struct rt_ringbuffer *rb,
327                                          rt_uint16_t           length)
328 {
329     rt_uint16_t space_length;
330     RT_ASSERT(rb != RT_NULL);
331 
332     /* whether has enough space */
333     space_length = rt_ringbuffer_space_len(rb);
334 
335     if (length > rb->buffer_size)
336     {
337         length = rb->buffer_size;
338 #if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG)
339         LOG_W("The serial buffer (len %d) is overflow.", rb->buffer_size);
340 #endif
341     }
342 
343     if (rb->buffer_size - rb->write_index > length)
344     {
345         /* this should not cause overflow because there is enough space for
346          * length of data in current mirror */
347         rb->write_index += length;
348 
349         if (length > space_length)
350             rb->read_index = rb->write_index;
351 
352         return;
353     }
354 
355     /* we are going into the other side of the mirror */
356     rb->write_mirror = ~rb->write_mirror;
357     rb->write_index  = length - (rb->buffer_size - rb->write_index);
358 
359     if (length > space_length)
360     {
361         if (rb->write_index <= rb->read_index)
362             rb->read_mirror = ~rb->read_mirror;
363         rb->read_index = rb->write_index;
364     }
365     return;
366 }
367 #endif /* RT_SERIAL_USING_DMA */
368 
369 /**
370   * @brief Serial polling receive data routine, This function will receive data
371   *        in a continuous loop by one by one byte.
372   * @param dev The pointer of device driver structure
373   * @param pos Empty parameter.
374   * @param buffer Receive data buffer.
375   * @param size Receive data buffer length.
376   * @return Return the final length of data received.
377   */
_serial_poll_rx(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)378 rt_ssize_t _serial_poll_rx(struct rt_device *dev,
379                            rt_off_t          pos,
380                            void             *buffer,
381                            rt_size_t         size)
382 {
383     struct rt_serial_device *serial;
384     rt_size_t                getc_size;
385     int                      getc_element; /* Gets one byte of data received */
386     rt_uint8_t              *getc_buffer;  /* Pointer to the receive data buffer */
387 
388     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
389     if (size == 0) return 0;
390 
391     serial      = (struct rt_serial_device *)dev;
392     getc_buffer = (rt_uint8_t *)buffer;
393     getc_size   = size;
394 
395     while (size)
396     {
397         getc_element = serial->ops->getc(serial);
398         if (getc_element < 0) break;
399 
400         *getc_buffer = getc_element;
401 
402         ++getc_buffer;
403         --size;
404 
405         if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
406         {
407             /* If open_flag satisfies RT_DEVICE_FLAG_STREAM
408              * and the received character is '\n', exit the loop directly */
409             if (getc_element == '\n') break;
410         }
411     }
412 
413     return getc_size - size;
414 }
415 
416 /**
417   * @brief Serial polling transmit data routines, This function will transmit
418   *        data in a continuous loop by one by one byte.
419   * @param dev The pointer of device driver structure
420   * @param pos Empty parameter.
421   * @param buffer Transmit data buffer.
422   * @param size Transmit data buffer length.
423   * @return Return the final length of data transmit.
424   */
_serial_poll_tx(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)425 rt_ssize_t _serial_poll_tx(struct rt_device *dev,
426                            rt_off_t          pos,
427                            const void       *buffer,
428                            rt_size_t         size)
429 {
430     struct rt_serial_device *serial;
431     rt_size_t                putc_size;
432     rt_uint8_t              *putc_buffer; /* Pointer to the transmit data buffer */
433     int                      putc_result;
434 
435     if (size == 0) return 0;
436     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
437 
438     serial      = (struct rt_serial_device *)dev;
439     putc_buffer = (rt_uint8_t *)buffer;
440     putc_size   = size;
441 
442     while (size)
443     {
444         if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
445         {
446             /* If open_flag satisfies RT_DEVICE_FLAG_STREAM and the received character is '\n',
447              * inserts '\r' character before '\n' character for the effect of carriage return newline */
448             if (*putc_buffer == '\n')
449                 serial->ops->putc(serial, '\r');
450         }
451         putc_result = serial->ops->putc(serial, *putc_buffer);
452         if (putc_result < 0) break;
453 
454         ++putc_buffer;
455         --size;
456     }
457 
458     return putc_size - size;
459 }
460 
461 /**
462   * @brief Serial receive data routines, This function will receive
463   *        data by using fifo
464   *
465   * @note In blocking mode, the function will wait until the specified amount of data is received or until a timeout occurs.
466   *       In non-blocking mode, the function will immediately attempt to retrieve as much data as possible from the ring buffer and return.
467   *
468   * @param dev The pointer of device driver structure
469   * @param pos Empty parameter.
470   * @param buffer Receive data buffer.
471   * @param size Receive data buffer length.
472   * @return Returns the actual length of data received.
473   */
_serial_fifo_rx(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)474 static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
475                                   rt_off_t          pos,
476                                   void             *buffer,
477                                   rt_size_t         size)
478 {
479     struct rt_serial_device  *serial;
480     struct rt_serial_rx_fifo *rx_fifo;
481     rt_base_t                 level;
482     rt_size_t                 recv_size = 0;
483 
484     if (size == 0) return 0;
485     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
486 
487     serial  = (struct rt_serial_device *)dev;
488     rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
489 
490     if (dev->open_flag & RT_SERIAL_RX_BLOCKING)
491     {
492         rt_size_t  data_len;
493         rt_tick_t  delta_tick;
494         rt_size_t  rx_bufsz_third  = serial->config.rx_bufsz / 2;
495         rt_int32_t base_rx_timeout = rt_atomic_load(&rx_fifo->rx_timeout);
496         rt_int32_t rx_timeout_left = base_rx_timeout;
497         rt_tick_t  begin_tick      = rt_tick_get();
498 
499         while (1)
500         {
501             if (rx_timeout_left != RT_WAITING_NO)
502             {
503                 level    = rt_spin_lock_irqsave(&serial->spinlock);
504                 data_len = rt_ringbuffer_data_len(&rx_fifo->rb);
505                 if (data_len < size - recv_size)
506                 {
507                     if (size - (recv_size + data_len) >= rx_bufsz_third)
508                     {
509                         rx_fifo->rx_cpt_index = rx_bufsz_third;
510                     }
511                     else
512                     {
513                         rx_fifo->rx_cpt_index = size - (recv_size + data_len);
514                     }
515                     rt_completion_wait(&rx_fifo->rx_cpt, 0);
516                 }
517                 rt_spin_unlock_irqrestore(&serial->spinlock, level);
518             }
519 
520             level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
521             recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
522             RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
523             if (recv_size == size || rx_timeout_left == RT_WAITING_NO)
524             {
525                 break;
526             }
527 
528             rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout_left);
529             if (rx_timeout_left != RT_WAITING_FOREVER)
530             {
531                 delta_tick = rt_tick_get_delta(begin_tick);
532                 if (delta_tick >= base_rx_timeout)
533                 {
534                     level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
535                     recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
536                     RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
537                     return recv_size;
538                 }
539 
540                 rx_timeout_left = base_rx_timeout - delta_tick;
541             }
542         }
543     }
544     else if (dev->open_flag & RT_SERIAL_RX_NON_BLOCKING)
545     {
546         /* When open_flag is RT_SERIAL_RX_NON_BLOCKING,
547          * the data is retrieved directly from the ringbuffer and returned */
548         level     = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
549         recv_size = rt_ringbuffer_get(&rx_fifo->rb, buffer, size);
550         RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
551     }
552 
553     return recv_size;
554 }
555 
556 /**
557   * @brief Serial transmit data routines, This function will transmit
558   *        data by using blocking_nbuf.
559   * @param dev The pointer of device driver structure
560   * @param pos Empty parameter.
561   * @param buffer Transmit data buffer.
562   * @param size Transmit data buffer length.
563   * @return Returns the actual length of data transmitted.
564   */
_serial_fifo_tx_blocking_nbuf(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)565 static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
566                                                 rt_off_t          pos,
567                                                 const void       *buffer,
568                                                 rt_size_t         size)
569 {
570     struct rt_serial_device  *serial;
571     struct rt_serial_tx_fifo *tx_fifo;
572     rt_ssize_t                send_size;
573     rt_err_t                  ret;
574 
575     if (size == 0) return 0;
576     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
577 
578     serial  = (struct rt_serial_device *)dev;
579     tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
580     RT_ASSERT(tx_fifo != RT_NULL);
581 
582     if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
583     {
584         /* using poll tx when the scheduler not startup or in stream mode */
585         return _serial_poll_tx(dev, pos, buffer, size);
586     }
587 
588     /* When serial transmit in tx_blocking mode,
589      * if the activated mode is RT_TRUE, it will return directly */
590     if (rt_atomic_flag_test_and_set(&tx_fifo->activated))
591     {
592         return 0;
593     }
594 
595     /* clear tx_cpt flag */
596     rt_completion_wait(&tx_fifo->tx_cpt, 0);
597 
598     /* Call the transmit interface for transmission */
599     send_size = serial->ops->transmit(serial,
600                                       (rt_uint8_t *)buffer,
601                                       size,
602                                       RT_SERIAL_TX_BLOCKING);
603     if (send_size <= 0)
604     {
605         return 0;
606     }
607 
608     if (rt_atomic_load(&tx_fifo->tx_timeout) == RT_WAITING_NO)
609     {
610         /* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
611 #ifdef RT_USING_POSIX_STDIO
612         if (serial->is_posix_mode)
613             return send_size;
614 #endif
615         return 0;
616     }
617 
618     /* Waiting for the transmission to complete */
619     ret = rt_completion_wait(&tx_fifo->tx_cpt, rt_atomic_load(&tx_fifo->tx_timeout));
620     if (ret != RT_EOK)
621     {
622         /* Cannot get the number of bytes sent under DMA, so returns 0 directly */
623         return 0;
624     }
625 
626     return send_size;
627 }
628 
629 /**
630   * @brief Serial transmit data routines, This function will transmit
631   *        data by using blocking_buf.
632   * @param dev The pointer of device driver structure
633   * @param pos Empty parameter.
634   * @param buffer Transmit data buffer.
635   * @param size Transmit data buffer length.
636   * @return Returns the final length of data transmitted.
637   */
_serial_fifo_tx_blocking_buf(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)638 static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
639                                                rt_off_t          pos,
640                                                const void       *buffer,
641                                                rt_size_t         size)
642 {
643     struct rt_serial_device  *serial;
644     struct rt_serial_tx_fifo *tx_fifo;
645     rt_base_t                 level;
646 
647     if (size == 0) return 0;
648     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
649 
650     serial  = (struct rt_serial_device *)dev;
651     tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
652     RT_ASSERT(tx_fifo != RT_NULL);
653 
654     if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
655     {
656         /* using poll tx when the scheduler not startup or in stream mode */
657         return _serial_poll_tx(dev, pos, buffer, size);
658     }
659 
660     /* When serial transmit in tx_blocking mode,
661      * if the activated mode is RT_TRUE, it will return directly */
662     if (rt_atomic_flag_test_and_set(&tx_fifo->activated))
663     {
664         return 0;
665     }
666 
667     rt_tick_t  delta_tick;
668     rt_int32_t base_tx_timeout = rt_atomic_load(&tx_fifo->tx_timeout);
669     rt_int32_t tx_timeout_left = base_tx_timeout;
670     rt_tick_t  begin_tick      = rt_tick_get();
671     rt_size_t  send_size       = 0;
672     rt_size_t  rb_size;
673     rt_ssize_t transmit_size;
674 
675     while (send_size != size)
676     {
677         /* Copy one piece of data into the ringbuffer at a time
678          * until the length of the data is equal to size */
679         level             = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
680         tx_fifo->put_size = rt_ringbuffer_put(&tx_fifo->rb,
681                                               (rt_uint8_t *)buffer + send_size,
682                                               size - send_size);
683         rb_size           = rt_ringbuffer_data_len(&tx_fifo->rb);
684         RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
685 
686         /* clear tx_cpt flag */
687         rt_completion_wait(&tx_fifo->tx_cpt, 0);
688 
689         /* Call the transmit interface for transmission again */
690         /* Note that in interrupt mode, buffer and tx_fifo->put_size
691          * are inactive parameters */
692         transmit_size = serial->ops->transmit(serial,
693                                               (rt_uint8_t *)buffer + send_size,
694                                               tx_fifo->put_size,
695                                               RT_SERIAL_TX_BLOCKING);
696         if (transmit_size <= 0)
697         {
698             return send_size;
699         }
700 
701         if (tx_timeout_left == RT_WAITING_NO)
702         {
703             /* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
704 #ifdef RT_USING_POSIX_STDIO
705             if (serial->is_posix_mode)
706                 send_size += tx_fifo->put_size;
707 #endif
708             break;
709         }
710 
711         /* Waiting for the transmission to complete */
712         rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout_left);
713         if (tx_timeout_left != RT_WAITING_FOREVER)
714         {
715             delta_tick = rt_tick_get_delta(begin_tick);
716             if (delta_tick >= base_tx_timeout)
717             {
718                 level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
719                 send_size += rb_size - rt_ringbuffer_data_len(&tx_fifo->rb);
720                 RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
721                 return send_size;
722             }
723 
724             tx_timeout_left = base_tx_timeout - delta_tick;
725         }
726 
727         send_size += tx_fifo->put_size;
728     }
729 
730 
731     return send_size;
732 }
733 
734 /**
735   * @brief Serial transmit data routines, This function will transmit
736   *        data by using nonblocking.
737   * @param dev The pointer of device driver structure
738   * @param pos Empty parameter.
739   * @param buffer Transmit data buffer.
740   * @param size Transmit data buffer length.
741   * @return Return the final length of data transmit.
742   */
_serial_fifo_tx_nonblocking(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)743 static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
744                                               rt_off_t          pos,
745                                               const void       *buffer,
746                                               rt_size_t         size)
747 {
748     struct rt_serial_device  *serial;
749     struct rt_serial_tx_fifo *tx_fifo;
750     rt_uint8_t               *put_ptr;
751     rt_base_t                 level;
752     rt_size_t                 send_size;
753     rt_ssize_t                transmit_size;
754 
755     if (size == 0) return 0;
756     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
757 
758     serial  = (struct rt_serial_device *)dev;
759     tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
760     RT_ASSERT(tx_fifo != RT_NULL);
761 
762     /* When serial transmit in tx_non_blocking mode, if the activated mode is RT_FALSE,
763          * start copying data into the ringbuffer */
764     if (!rt_atomic_flag_test_and_set(&tx_fifo->activated))
765     {
766         level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
767         /* Copying data into the ringbuffer */
768         send_size = rt_ringbuffer_put(&tx_fifo->rb, buffer, size);
769 
770         /* Get the linear length buffer from ringbuffer */
771         tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr);
772         RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
773 
774         /* clear tx_cpt flag */
775         rt_completion_wait(&tx_fifo->tx_cpt, 0);
776 
777         /* Call the transmit interface for transmission again */
778         /* Note that in interrupt mode, put_ptr and tx_fifo->put_size
779          * are inactive parameters */
780         transmit_size = serial->ops->transmit(serial,
781                                               put_ptr,
782                                               tx_fifo->put_size,
783                                               RT_SERIAL_TX_NON_BLOCKING);
784         if (transmit_size <= 0)
785         {
786             return 0;
787         }
788         /* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait
789          * for the rt_current_thread to resume */
790         return send_size;
791     }
792 
793     /* If the activated mode is RT_TRUE, it means that serial device is transmitting,
794      * where only the data in the ringbuffer and there is no need to call the transmit() API.
795      * Note that this part of the code requires disable interrupts
796      * to prevent multi thread reentrant */
797 
798     level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
799     /* Copying data into the ringbuffer */
800     send_size = rt_ringbuffer_put(&tx_fifo->rb, buffer, size);
801     RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
802 
803     return send_size;
804 }
805 
806 
807 /**
808   * @brief Enable serial transmit mode.
809   * @param dev The pointer of device driver structure
810   * @param rx_oflag The flag of that the serial port opens.
811   * @return Return the status of the operation.
812   */
rt_serial_tx_enable(struct rt_device * dev,rt_uint16_t tx_oflag)813 static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
814                                     rt_uint16_t       tx_oflag)
815 {
816     struct rt_serial_device  *serial;
817     struct rt_serial_tx_fifo *tx_fifo        = RT_NULL;
818     rt_err_t                  control_result = RT_EOK;
819 
820     RT_ASSERT(dev != RT_NULL);
821     serial = (struct rt_serial_device *)dev;
822 
823     if (serial->config.tx_bufsz == 0)
824     {
825         /* Cannot use RT_SERIAL_TX_NON_BLOCKING when tx_bufsz is 0 */
826         if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING)
827         {
828             LOG_E("(%s) serial device with misconfigure: tx_bufsz = 0",
829                   dev->parent.name);
830             return -RT_EINVAL;
831         }
832 
833 #ifndef RT_USING_DEVICE_OPS
834         dev->write = _serial_poll_tx;
835 #endif
836 
837         dev->open_flag |= RT_SERIAL_TX_BLOCKING;
838         return RT_EOK;
839     }
840     /* Limits the minimum value of tx_bufsz */
841     if (serial->config.tx_bufsz < RT_SERIAL_TX_MINBUFSZ)
842         serial->config.tx_bufsz = RT_SERIAL_TX_MINBUFSZ;
843 
844     if (tx_oflag == RT_SERIAL_TX_BLOCKING)
845     {
846         /* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine
847          * whether serial device needs to use buffer */
848         /* Call the Control() API to get the operating mode */
849         control_result = serial->ops->control(serial,
850                                               RT_DEVICE_CHECK_OPTMODE,
851                                               (void *)RT_DEVICE_FLAG_TX_BLOCKING);
852         if (control_result < 0)
853         {
854             return control_result;
855         }
856 
857         rt_err_t optmode = control_result;
858         if (optmode == RT_SERIAL_TX_BLOCKING_BUFFER)
859         {
860             /* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */
861             tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz);
862             RT_ASSERT(tx_fifo != RT_NULL);
863             rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz);
864             rt_ringbuffer_init(&tx_fifo->rb,
865                                (rt_uint8_t *)tx_fifo + sizeof(struct rt_serial_tx_fifo),
866                                serial->config.tx_bufsz);
867             serial->serial_tx = tx_fifo;
868 
869 #ifndef RT_USING_DEVICE_OPS
870             dev->write = _serial_fifo_tx_blocking_buf;
871 #endif
872         }
873         else if (optmode == RT_SERIAL_TX_BLOCKING_NO_BUFFER)
874         {
875             /* If not use RT_SERIAL_TX_BLOCKING_BUFFER,
876              * the control() API is called to configure the serial device */
877             tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo));
878             RT_ASSERT(tx_fifo != RT_NULL);
879             rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo));
880             /* Init rb.buffer_ptr to RT_NULL, in rt_serial_write() need check it
881              * otherwise buffer_ptr maybe a random value, as rt_malloc not init memory */
882             serial->serial_tx = tx_fifo;
883 
884 #ifndef RT_USING_DEVICE_OPS
885             dev->write = _serial_fifo_tx_blocking_nbuf;
886 #endif
887 
888             /* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/
889             control_result = serial->ops->control(serial,
890                                                   RT_DEVICE_CTRL_CONFIG,
891                                                   (void *)RT_SERIAL_TX_BLOCKING);
892             if (control_result < 0)
893             {
894                 goto __exit;
895             }
896         }
897         else
898         {
899             return -RT_EIO;
900         }
901         rt_atomic_flag_clear(&tx_fifo->activated);
902         tx_fifo->put_size = 0;
903         rt_atomic_store(&tx_fifo->tx_timeout, RT_WAITING_FOREVER);
904 
905         rt_completion_init(&tx_fifo->tx_cpt);
906         dev->open_flag |= RT_SERIAL_TX_BLOCKING;
907 
908         return RT_EOK;
909     }
910 
911     /* When using RT_SERIAL_TX_NON_BLOCKING, ringbuffer needs to be initialized,
912      * and initialize the tx_fifo->activated value is RT_FALSE.
913      */
914     tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz);
915     RT_ASSERT(tx_fifo != RT_NULL);
916     rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz);
917 
918     rt_ringbuffer_init(&tx_fifo->rb,
919                        (rt_uint8_t *)tx_fifo + sizeof(struct rt_serial_tx_fifo),
920                        serial->config.tx_bufsz);
921     serial->serial_tx = tx_fifo;
922 
923     rt_atomic_flag_clear(&tx_fifo->activated);
924     tx_fifo->put_size = 0;
925 
926 #ifndef RT_USING_DEVICE_OPS
927     dev->write = _serial_fifo_tx_nonblocking;
928 #endif
929 
930     rt_completion_init(&tx_fifo->tx_cpt);
931     dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING;
932 
933     /* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/
934     control_result = serial->ops->control(serial,
935                                           RT_DEVICE_CTRL_CONFIG,
936                                           (void *)RT_SERIAL_TX_NON_BLOCKING);
937 
938 __exit:
939     return control_result;
940 }
941 
942 
943 /**
944   * @brief Enable serial receive mode.
945   * @param dev The pointer of device driver structure
946   * @param rx_oflag The flag of that the serial port opens.
947   * @return Return the status of the operation.
948   */
rt_serial_rx_enable(struct rt_device * dev,rt_uint16_t rx_oflag)949 static rt_err_t rt_serial_rx_enable(struct rt_device *dev,
950                                     rt_uint16_t       rx_oflag)
951 {
952     struct rt_serial_device  *serial;
953     struct rt_serial_rx_fifo *rx_fifo      = RT_NULL;
954     rt_size_t                 rx_fifo_size = 0;
955 
956     RT_ASSERT(dev != RT_NULL);
957     serial = (struct rt_serial_device *)dev;
958 
959     if (serial->config.rx_bufsz == 0)
960     {
961         /* Cannot use RT_SERIAL_RX_NON_BLOCKING when rx_bufsz is 0 */
962         if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING)
963         {
964             LOG_E("(%s) serial device with misconfigure: rx_bufsz = 0",
965                   dev->parent.name);
966             return -RT_EINVAL;
967         }
968 
969 #ifndef RT_USING_DEVICE_OPS
970         dev->read = _serial_poll_rx;
971 #endif
972 
973         dev->open_flag |= RT_SERIAL_RX_BLOCKING;
974         return RT_EOK;
975     }
976     /* Limits the minimum value of rx_bufsz */
977     if (serial->config.rx_bufsz < RT_SERIAL_RX_MINBUFSZ)
978         serial->config.rx_bufsz = RT_SERIAL_RX_MINBUFSZ;
979 
980 #ifdef RT_SERIAL_USING_DMA
981     if (serial->config.dma_ping_bufsz < RT_SERIAL_RX_MINBUFSZ / 2)
982         serial->config.dma_ping_bufsz = RT_SERIAL_RX_MINBUFSZ / 2;
983     rx_fifo_size = sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz + serial->config.dma_ping_bufsz;
984 #else
985     rx_fifo_size = sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz;
986 #endif
987 
988     rx_fifo = (struct rt_serial_rx_fifo *)rt_malloc(rx_fifo_size);
989     RT_ASSERT(rx_fifo != RT_NULL);
990     rt_memset(rx_fifo, RT_NULL, rx_fifo_size);
991 
992     rt_ringbuffer_init(&rx_fifo->rb,
993                        (rt_uint8_t *)rx_fifo + sizeof(struct rt_serial_rx_fifo),
994                        serial->config.rx_bufsz);
995 
996 #ifdef RT_SERIAL_USING_DMA
997     rt_ringbuffer_init(&rx_fifo->dma_ping_rb,
998                        (rt_uint8_t *)rx_fifo + sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz,
999                        serial->config.dma_ping_bufsz);
1000 #endif
1001 
1002     serial->serial_rx = rx_fifo;
1003 
1004 #ifndef RT_USING_DEVICE_OPS
1005     dev->read = _serial_fifo_rx;
1006 #endif
1007 
1008     if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING)
1009     {
1010         dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING;
1011         /* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/
1012         return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_NON_BLOCKING);
1013     }
1014 
1015     /* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */
1016     rx_fifo->rx_cpt_index = 0;
1017     rt_atomic_store(&rx_fifo->rx_timeout, RT_WAITING_FOREVER);
1018 
1019     rt_completion_init(&rx_fifo->rx_cpt);
1020     dev->open_flag |= RT_SERIAL_RX_BLOCKING;
1021     /* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/
1022     return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_BLOCKING);
1023 }
1024 
1025 /**
1026   * @brief Disable serial receive mode.
1027   * @param dev The pointer of device driver structure
1028   * @param rx_oflag The flag of that the serial port opens.
1029   * @return Return the status of the operation.
1030   */
rt_serial_rx_disable(struct rt_device * dev,rt_uint16_t rx_oflag)1031 static rt_err_t rt_serial_rx_disable(struct rt_device *dev,
1032                                      rt_uint16_t       rx_oflag)
1033 {
1034     struct rt_serial_device  *serial;
1035     struct rt_serial_rx_fifo *rx_fifo;
1036 
1037     RT_ASSERT(dev != RT_NULL);
1038     serial = (struct rt_serial_device *)dev;
1039 
1040 #ifndef RT_USING_DEVICE_OPS
1041     dev->read = RT_NULL;
1042 #endif
1043 
1044     if (serial->serial_rx == RT_NULL) return RT_EOK;
1045 
1046     rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
1047     RT_ASSERT(rx_fifo != RT_NULL);
1048 
1049     if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING)
1050     {
1051         dev->open_flag &= ~RT_SERIAL_RX_NON_BLOCKING;
1052         /* disable ignore return value */
1053         serial->ops->control(serial,
1054                              RT_DEVICE_CTRL_CLR_INT,
1055                              (void *)RT_SERIAL_RX_NON_BLOCKING);
1056     }
1057     else
1058     {
1059         rt_completion_done(&rx_fifo->rx_cpt);
1060         dev->open_flag &= ~RT_SERIAL_RX_BLOCKING;
1061         /* disable ignore return value */
1062         serial->ops->control(serial,
1063                              RT_DEVICE_CTRL_CLR_INT,
1064                              (void *)RT_SERIAL_RX_BLOCKING);
1065     }
1066 
1067     rt_free(rx_fifo);
1068     serial->serial_rx = RT_NULL;
1069 
1070     return RT_EOK;
1071 }
1072 
1073 /**
1074   * @brief Disable serial tranmit mode.
1075   * @param dev The pointer of device driver structure
1076   * @param rx_oflag The flag of that the serial port opens.
1077   * @return Return the status of the operation.
1078   */
rt_serial_tx_disable(struct rt_device * dev,rt_uint16_t tx_oflag)1079 static rt_err_t rt_serial_tx_disable(struct rt_device *dev,
1080                                      rt_uint16_t       tx_oflag)
1081 {
1082     struct rt_serial_device  *serial;
1083     struct rt_serial_tx_fifo *tx_fifo;
1084 
1085     RT_ASSERT(dev != RT_NULL);
1086     serial = (struct rt_serial_device *)dev;
1087 
1088 #ifndef RT_USING_DEVICE_OPS
1089     dev->write = RT_NULL;
1090 #endif
1091 
1092     if (serial->serial_tx == RT_NULL) return RT_EOK;
1093 
1094     tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
1095     RT_ASSERT(tx_fifo != RT_NULL);
1096 
1097     if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING)
1098     {
1099         dev->open_flag &= ~RT_SERIAL_TX_NON_BLOCKING;
1100         /* disable ignore return value */
1101         serial->ops->control(serial,
1102                              RT_DEVICE_CTRL_CLR_INT,
1103                              (void *)RT_SERIAL_TX_NON_BLOCKING);
1104     }
1105     else
1106     {
1107         rt_completion_done(&tx_fifo->tx_cpt);
1108         dev->open_flag &= ~RT_SERIAL_TX_BLOCKING;
1109         /* disable ignore return value */
1110         serial->ops->control(serial,
1111                              RT_DEVICE_CTRL_CLR_INT,
1112                              (void *)RT_SERIAL_TX_BLOCKING);
1113     }
1114 
1115 
1116     rt_free(tx_fifo);
1117     serial->serial_tx = RT_NULL;
1118     return RT_EOK;
1119 }
1120 
1121 /**
1122   * @brief Initialize the serial device.
1123   * @param dev The pointer of device driver structure
1124   * @return Return the status of the operation.
1125   */
rt_serial_init(struct rt_device * dev)1126 static rt_err_t rt_serial_init(struct rt_device *dev)
1127 {
1128     rt_err_t                 result = RT_EOK;
1129     struct rt_serial_device *serial;
1130 
1131     RT_ASSERT(dev != RT_NULL);
1132     serial = (struct rt_serial_device *)dev;
1133     RT_ASSERT(serial->ops->transmit != RT_NULL);
1134 
1135     /* initialize rx/tx */
1136     serial->serial_rx = RT_NULL;
1137     serial->serial_tx = RT_NULL;
1138 
1139     /* apply configuration */
1140     if (serial->ops->configure)
1141         result = serial->ops->configure(serial, &serial->config);
1142 
1143     return result;
1144 }
1145 
1146 /**
1147   * @brief Close the serial device.
1148   * @param dev The pointer of device driver structure
1149   * @return Return the status of the operation.
1150   */
rt_serial_close(struct rt_device * dev)1151 static rt_err_t rt_serial_close(struct rt_device *dev)
1152 {
1153     struct rt_serial_device *serial;
1154 
1155     RT_ASSERT(dev != RT_NULL);
1156     serial = (struct rt_serial_device *)dev;
1157 
1158     /* Disable serial receive mode. */
1159     rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
1160     /* Disable serial tranmit mode. */
1161     rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
1162 
1163     /* Clear the callback function */
1164     serial->parent.rx_indicate = RT_NULL;
1165     serial->parent.tx_complete = RT_NULL;
1166 
1167     rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify));
1168 
1169     /* Call the control() API to close the serial device. disable ignore return value */
1170     serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
1171     dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
1172 
1173     return RT_EOK;
1174 }
1175 
1176 /**
1177   * @brief Open the serial device.
1178   * @param dev The pointer of device driver structure
1179   * @param oflag The flag of that the serial port opens.
1180   * @return Return the status of the operation.
1181   */
rt_serial_open(struct rt_device * dev,rt_uint16_t oflag)1182 static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
1183 {
1184     struct rt_serial_device *serial;
1185     rt_err_t                 result = RT_EOK;
1186 
1187     RT_ASSERT(dev != RT_NULL);
1188     serial = (struct rt_serial_device *)dev;
1189 
1190     LOG_D("open serial device: 0x%08x with open flag: 0x%04x", dev, oflag);
1191 
1192     /* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */
1193     if ((oflag & RT_SERIAL_RX_BLOCKING) == RT_SERIAL_RX_BLOCKING)
1194         dev->open_flag |= RT_SERIAL_RX_BLOCKING;
1195     else
1196         dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING;
1197 
1198     /* By default, the transmit mode of a serial devide is RT_SERIAL_TX_BLOCKING */
1199     if ((oflag & RT_SERIAL_TX_NON_BLOCKING) == RT_SERIAL_TX_NON_BLOCKING)
1200         dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING;
1201     else
1202         dev->open_flag |= RT_SERIAL_TX_BLOCKING;
1203 
1204     /* set steam flag */
1205     if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM))
1206         dev->open_flag |= RT_DEVICE_FLAG_STREAM;
1207 
1208     /* initialize the Rx structure according to open flag */
1209     if (serial->serial_rx == RT_NULL)
1210     {
1211         result = rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
1212         if (result != RT_EOK)
1213         {
1214             rt_serial_close(dev);
1215             goto __exit;
1216         }
1217     }
1218 
1219     /* initialize the Tx structure according to open flag */
1220     if (serial->serial_tx == RT_NULL)
1221     {
1222         result = rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
1223         if (result != RT_EOK)
1224         {
1225             rt_serial_close(dev);
1226             goto __exit;
1227         }
1228     }
1229 
1230 __exit:
1231     return result;
1232 }
1233 
1234 
_serial_rx_flush(struct rt_serial_device * serial)1235 static void _serial_rx_flush(struct rt_serial_device *serial)
1236 {
1237     rt_base_t                 level;
1238     struct rt_serial_rx_fifo *rx_fifo;
1239     RT_ASSERT(serial != RT_NULL);
1240 
1241     if (serial->config.rx_bufsz == 0)
1242     {
1243         rt_uint32_t rx_flush_limit = 0xFFFFFFF;
1244         while (serial->ops->getc(serial) != -1 && rx_flush_limit > 0)
1245         {
1246             rx_flush_limit--;
1247         }
1248     }
1249     else
1250     {
1251         rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
1252         RT_ASSERT(rx_fifo != RT_NULL);
1253 
1254         level = rt_spin_lock_irqsave(&serial->spinlock);
1255         rt_completion_wait(&rx_fifo->rx_cpt, 0);
1256         rt_ringbuffer_reset(&rx_fifo->rb);
1257         rx_fifo->rx_cpt_index = 0;
1258 #ifdef RT_SERIAL_USING_DMA
1259         rt_serial_update_read_index(&rx_fifo->dma_ping_rb, rt_ringbuffer_get_size(&rx_fifo->dma_ping_rb));
1260 #endif
1261         rt_spin_unlock_irqrestore(&serial->spinlock, level);
1262     }
1263 }
1264 
_serial_tx_flush(struct rt_serial_device * serial)1265 static void _serial_tx_flush(struct rt_serial_device *serial)
1266 {
1267     struct rt_serial_tx_fifo *tx_fifo;
1268     RT_ASSERT(serial != RT_NULL);
1269 
1270     if (serial->config.tx_bufsz != 0)
1271     {
1272         tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
1273         RT_ASSERT(tx_fifo != RT_NULL);
1274 
1275         if (rt_atomic_load(&tx_fifo->activated))
1276         {
1277             rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER);
1278         }
1279     }
1280 }
1281 
_serial_get_unread_bytes_count(struct rt_serial_device * serial,rt_ssize_t * unread_bytes)1282 static rt_err_t _serial_get_unread_bytes_count(struct rt_serial_device *serial, rt_ssize_t *unread_bytes)
1283 {
1284     rt_base_t                 level;
1285     struct rt_serial_rx_fifo *rx_fifo;
1286     RT_ASSERT(serial != RT_NULL);
1287 
1288     if (serial->config.rx_bufsz == 0)
1289     {
1290         LOG_W("get unread bytes count not support in poll mode.");
1291         *unread_bytes = -1;
1292         return -RT_EPERM;
1293     }
1294 
1295     rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
1296     RT_ASSERT(rx_fifo != RT_NULL);
1297 
1298     level         = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
1299     *unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb);
1300     RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
1301 
1302     return RT_EOK;
1303 }
1304 
1305 #ifdef RT_USING_POSIX_TERMIOS
1306 struct speed_baudrate_item
1307 {
1308     speed_t speed;
1309     int     baudrate;
1310 };
1311 
1312 const static struct speed_baudrate_item _tbl[] =
1313     {
1314         {   B2400,    BAUD_RATE_2400},
1315         {   B4800,    BAUD_RATE_4800},
1316         {   B9600,    BAUD_RATE_9600},
1317         {  B19200,   BAUD_RATE_19200},
1318         {  B38400,   BAUD_RATE_38400},
1319         {  B57600,   BAUD_RATE_57600},
1320         { B115200,  BAUD_RATE_115200},
1321         { B230400,  BAUD_RATE_230400},
1322         { B460800,  BAUD_RATE_460800},
1323         { B500000,  BAUD_RATE_500000},
1324         { B921600,  BAUD_RATE_921600},
1325         {B2000000, BAUD_RATE_2000000},
1326         {B3000000, BAUD_RATE_3000000},
1327 };
1328 
_get_speed(int baudrate)1329 static speed_t _get_speed(int baudrate)
1330 {
1331     int index;
1332 
1333     for (index = 0; index < sizeof(_tbl) / sizeof(_tbl[0]); index++)
1334     {
1335         if (_tbl[index].baudrate == baudrate)
1336             return _tbl[index].speed;
1337     }
1338 
1339     return B0;
1340 }
1341 
_get_baudrate(speed_t speed)1342 static int _get_baudrate(speed_t speed)
1343 {
1344     int index;
1345 
1346     for (index = 0; index < sizeof(_tbl) / sizeof(_tbl[0]); index++)
1347     {
1348         if (_tbl[index].speed == speed)
1349             return _tbl[index].baudrate;
1350     }
1351 
1352     return 0;
1353 }
1354 
_tc_flush(struct rt_serial_device * serial,int queue)1355 static void _tc_flush(struct rt_serial_device *serial, int queue)
1356 {
1357     RT_ASSERT(serial != RT_NULL);
1358 
1359     if (queue == TCIFLUSH || queue == TCIOFLUSH)
1360     {
1361         _serial_rx_flush(serial);
1362     }
1363 
1364     if (queue == TCOFLUSH || queue == TCIOFLUSH)
1365     {
1366         _serial_tx_flush(serial);
1367     }
1368 }
1369 #endif /* RT_USING_POSIX_TERMIOS */
1370 
1371 /**
1372   * @brief Control the serial device.
1373   * @param dev The pointer of device driver structure
1374   * @param cmd The command value that controls the serial device
1375   * @param args The parameter value that controls the serial device
1376   * @return Return the status of the operation.
1377   */
rt_serial_control(struct rt_device * dev,int cmd,void * args)1378 static rt_err_t rt_serial_control(struct rt_device *dev,
1379                                   int               cmd,
1380                                   void             *args)
1381 {
1382     rt_err_t                 ret = RT_EOK;
1383     struct rt_serial_device *serial;
1384 
1385     RT_ASSERT(dev != RT_NULL);
1386     serial = (struct rt_serial_device *)dev;
1387 
1388     switch (cmd)
1389     {
1390     case RT_DEVICE_CTRL_SUSPEND:
1391         /* suspend device */
1392         dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
1393         break;
1394 
1395     case RT_DEVICE_CTRL_RESUME:
1396         /* resume device */
1397         dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
1398         break;
1399 
1400     case RT_DEVICE_CTRL_CONFIG:
1401         if (args == RT_NULL)
1402         {
1403             ret = -RT_EINVAL;
1404         }
1405         else
1406         {
1407             struct serial_configure *pconfig = (struct serial_configure *)args;
1408             if (((pconfig->rx_bufsz != serial->config.rx_bufsz)
1409                  || (pconfig->tx_bufsz != serial->config.tx_bufsz)
1410 #ifdef RT_SERIAL_USING_DMA
1411                  || (pconfig->dma_ping_bufsz != serial->config.dma_ping_bufsz)
1412 #endif
1413                      )
1414                 && serial->parent.ref_count != 0)
1415             {
1416                 /*can not change buffer size*/
1417                 ret = -RT_EBUSY;
1418                 break;
1419             }
1420             /* set serial configure */
1421             serial->config = *pconfig;
1422             serial->ops->configure(serial, (struct serial_configure *)args);
1423         }
1424         break;
1425     case RT_SERIAL_CTRL_GET_CONFIG:
1426         if (args == RT_NULL)
1427         {
1428             ret = -RT_EINVAL;
1429         }
1430         else
1431         {
1432             struct serial_configure *pconfig = (struct serial_configure *)args;
1433             *pconfig                         = serial->config;
1434         }
1435         break;
1436     case RT_DEVICE_CTRL_NOTIFY_SET:
1437         if (args == RT_NULL)
1438         {
1439             ret = -RT_EINVAL;
1440         }
1441         else
1442         {
1443             rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify));
1444         }
1445         break;
1446 
1447     case RT_DEVICE_CTRL_CONSOLE_OFLAG:
1448         if (args == RT_NULL)
1449         {
1450             ret = -RT_EINVAL;
1451         }
1452         else
1453         {
1454             *(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING | RT_DEVICE_FLAG_STREAM;
1455         }
1456         break;
1457 
1458     /* Call before rt_device_read */
1459     case RT_SERIAL_CTRL_SET_RX_TIMEOUT:
1460         if (args == RT_NULL)
1461         {
1462             ret = -RT_EINVAL;
1463         }
1464         else
1465         {
1466             if (serial->config.rx_bufsz == 0)
1467             {
1468                 ret = -RT_EPERM;
1469             }
1470 
1471             struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
1472             rx_fifo                           = (struct rt_serial_rx_fifo *)serial->serial_rx;
1473             RT_ASSERT(rx_fifo != RT_NULL);
1474 
1475             rt_atomic_store(&rx_fifo->rx_timeout, *(rt_int32_t *)args);
1476         }
1477         break;
1478 
1479     /* Call before rt_device_write */
1480     case RT_SERIAL_CTRL_SET_TX_TIMEOUT:
1481         if (args == RT_NULL)
1482         {
1483             ret = -RT_EINVAL;
1484         }
1485         else
1486         {
1487             if (serial->config.tx_bufsz == 0)
1488             {
1489                 ret = -RT_EPERM;
1490             }
1491 
1492             struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
1493             tx_fifo                           = (struct rt_serial_tx_fifo *)serial->serial_tx;
1494             RT_ASSERT(tx_fifo != RT_NULL);
1495 
1496             rt_atomic_store(&tx_fifo->tx_timeout, *(rt_int32_t *)args);
1497         }
1498         break;
1499 
1500     case RT_SERIAL_CTRL_GET_RX_TIMEOUT:
1501         if (args == RT_NULL)
1502         {
1503             ret = -RT_EINVAL;
1504         }
1505         else
1506         {
1507             if (serial->config.rx_bufsz == 0)
1508             {
1509                 ret = -RT_EPERM;
1510             }
1511 
1512             struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
1513             rx_fifo                           = (struct rt_serial_rx_fifo *)serial->serial_rx;
1514             RT_ASSERT(rx_fifo != RT_NULL);
1515 
1516             *(rt_int32_t *)args = rt_atomic_load(&rx_fifo->rx_timeout);
1517         }
1518         break;
1519 
1520     case RT_SERIAL_CTRL_GET_TX_TIMEOUT:
1521         if (args == RT_NULL)
1522         {
1523             ret = -RT_EINVAL;
1524         }
1525         else
1526         {
1527             if (serial->config.tx_bufsz == 0)
1528             {
1529                 ret = -RT_EPERM;
1530             }
1531 
1532             struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
1533             tx_fifo                           = (struct rt_serial_tx_fifo *)serial->serial_tx;
1534             RT_ASSERT(tx_fifo != RT_NULL);
1535 
1536             *(rt_int32_t *)args = rt_atomic_load(&tx_fifo->tx_timeout);
1537         }
1538         break;
1539 
1540     /* Discard all data */
1541     case RT_SERIAL_CTRL_RX_FLUSH:
1542         _serial_rx_flush(serial);
1543         break;
1544 
1545     /* Blocking and wait for the send buffer data to be sent. */
1546     case RT_SERIAL_CTRL_TX_FLUSH:
1547         _serial_tx_flush(serial);
1548         break;
1549 
1550     /* get unread bytes count. */
1551     case RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT:
1552         if (args == RT_NULL)
1553         {
1554             ret = -RT_EINVAL;
1555         }
1556         else
1557         {
1558             ret = _serial_get_unread_bytes_count(serial, (rt_ssize_t *)args);
1559         }
1560         break;
1561 
1562 #ifdef RT_USING_POSIX_STDIO
1563 #ifdef RT_USING_POSIX_TERMIOS
1564     case TCGETA: {
1565         struct termios *tio = (struct termios *)args;
1566         if (tio == RT_NULL) return -RT_EINVAL;
1567 
1568         tio->c_iflag = 0;
1569         tio->c_oflag = 0;
1570         tio->c_lflag = 0;
1571 
1572         /* update oflag for console device */
1573         if (rt_console_get_device() == dev)
1574             tio->c_oflag = OPOST | ONLCR;
1575 
1576         /* set cflag */
1577         tio->c_cflag = 0;
1578         if (serial->config.data_bits == DATA_BITS_5)
1579             tio->c_cflag = CS5;
1580         else if (serial->config.data_bits == DATA_BITS_6)
1581             tio->c_cflag = CS6;
1582         else if (serial->config.data_bits == DATA_BITS_7)
1583             tio->c_cflag = CS7;
1584         else if (serial->config.data_bits == DATA_BITS_8)
1585             tio->c_cflag = CS8;
1586 
1587         if (serial->config.stop_bits == STOP_BITS_2)
1588             tio->c_cflag |= CSTOPB;
1589 
1590         if (serial->config.parity == PARITY_EVEN)
1591             tio->c_cflag |= PARENB;
1592         else if (serial->config.parity == PARITY_ODD)
1593             tio->c_cflag |= (PARODD | PARENB);
1594 
1595         if (serial->config.flowcontrol == RT_SERIAL_FLOWCONTROL_CTSRTS)
1596             tio->c_cflag |= CRTSCTS;
1597 
1598         cfsetospeed(tio, _get_speed(serial->config.baud_rate));
1599     }
1600     break;
1601 
1602     case TCSETAW:
1603     case TCSETAF:
1604     case TCSETA: {
1605         int                     baudrate;
1606         struct serial_configure config;
1607 
1608         struct termios *tio = (struct termios *)args;
1609         if (tio == RT_NULL) return -RT_EINVAL;
1610 
1611         config = serial->config;
1612 
1613         baudrate         = _get_baudrate(cfgetospeed(tio));
1614         config.baud_rate = baudrate;
1615 
1616         switch (tio->c_cflag & CSIZE)
1617         {
1618         case CS5:
1619             config.data_bits = DATA_BITS_5;
1620             break;
1621         case CS6:
1622             config.data_bits = DATA_BITS_6;
1623             break;
1624         case CS7:
1625             config.data_bits = DATA_BITS_7;
1626             break;
1627         default:
1628             config.data_bits = DATA_BITS_8;
1629             break;
1630         }
1631 
1632         if (tio->c_cflag & CSTOPB)
1633             config.stop_bits = STOP_BITS_2;
1634         else
1635             config.stop_bits = STOP_BITS_1;
1636 
1637         if (tio->c_cflag & PARENB)
1638         {
1639             if (tio->c_cflag & PARODD)
1640                 config.parity = PARITY_ODD;
1641             else
1642                 config.parity = PARITY_EVEN;
1643         }
1644         else
1645             config.parity = PARITY_NONE;
1646 
1647         if (tio->c_cflag & CRTSCTS)
1648             config.flowcontrol = RT_SERIAL_FLOWCONTROL_CTSRTS;
1649         else
1650             config.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE;
1651 
1652         /* set serial configure */
1653         serial->config = config;
1654         serial->ops->configure(serial, &config);
1655     }
1656     break;
1657     case TCFLSH: {
1658         int queue = (int)args;
1659 
1660         _tc_flush(serial, queue);
1661     }
1662 
1663     break;
1664     case TCXONC:
1665         break;
1666 #endif /*RT_USING_POSIX_TERMIOS*/
1667     case TIOCSWINSZ: {
1668         struct winsize *p_winsize;
1669 
1670         p_winsize = (struct winsize *)args;
1671         rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row);
1672     }
1673     break;
1674     case TIOCGWINSZ: {
1675         struct winsize *p_winsize;
1676         p_winsize = (struct winsize *)args;
1677 
1678         if (rt_thread_self() != rt_thread_find(FINSH_THREAD_NAME))
1679         {
1680             /* only can be used in tshell thread; otherwise, return default size */
1681             p_winsize->ws_col = 80;
1682             p_winsize->ws_row = 24;
1683         }
1684         else
1685         {
1686 #include <shell.h>
1687 #define _TIO_BUFLEN 20
1688             char          _tio_buf[_TIO_BUFLEN];
1689             unsigned char cnt1, cnt2, cnt3, i;
1690             char          row_s[4], col_s[4];
1691             char         *p;
1692 
1693             rt_memset(_tio_buf, 0, _TIO_BUFLEN);
1694 
1695             /* send the command to terminal for getting the window size of the terminal */
1696             rt_kprintf("\033[18t");
1697 
1698             /* waiting for the response from the terminal */
1699             i = 0;
1700             while (i < _TIO_BUFLEN)
1701             {
1702                 _tio_buf[i] = finsh_getchar();
1703                 if (_tio_buf[i] != 't')
1704                 {
1705                     i++;
1706                 }
1707                 else
1708                 {
1709                     break;
1710                 }
1711             }
1712             if (i == _TIO_BUFLEN)
1713             {
1714                 /* buffer overloaded, and return default size */
1715                 p_winsize->ws_col = 80;
1716                 p_winsize->ws_row = 24;
1717                 break;
1718             }
1719 
1720             /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */
1721             rt_memset(row_s, 0, 4);
1722             rt_memset(col_s, 0, 4);
1723             cnt1 = 0;
1724             while (cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';')
1725             {
1726                 cnt1++;
1727             }
1728             cnt2 = ++cnt1;
1729             while (cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';')
1730             {
1731                 cnt2++;
1732             }
1733             p = row_s;
1734             while (cnt1 < cnt2)
1735             {
1736                 *p++ = _tio_buf[cnt1++];
1737             }
1738             p = col_s;
1739             cnt2++;
1740             cnt3 = rt_strlen(_tio_buf) - 1;
1741             while (cnt2 < cnt3)
1742             {
1743                 *p++ = _tio_buf[cnt2++];
1744             }
1745 
1746             /* load the window size date */
1747             p_winsize->ws_col = atoi(col_s);
1748             p_winsize->ws_row = atoi(row_s);
1749 #undef _TIO_BUFLEN
1750         }
1751 
1752         p_winsize->ws_xpixel = 0; /* unused */
1753         p_winsize->ws_ypixel = 0; /* unused */
1754     }
1755     break;
1756     case FIONREAD:
1757         if (args == RT_NULL)
1758         {
1759             ret = -RT_EINVAL;
1760         }
1761         else
1762         {
1763             rt_ssize_t unread_bytes = 0;
1764             ret                     = _serial_get_unread_bytes_count(serial, &unread_bytes);
1765             if (ret == RT_EOK)
1766                 *(rt_size_t *)args = (rt_size_t)unread_bytes;
1767             else
1768                 *(rt_size_t *)args = 0;
1769         }
1770         break;
1771 #endif /* RT_USING_POSIX_STDIO */
1772     default:
1773         /* control device */
1774         ret = serial->ops->control(serial, cmd, args);
1775         break;
1776     }
1777 
1778     return ret;
1779 }
1780 
1781 #ifdef RT_USING_DEVICE_OPS
rt_serial_read(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)1782 static rt_ssize_t rt_serial_read(struct rt_device *dev,
1783                                  rt_off_t          pos,
1784                                  void             *buffer,
1785                                  rt_size_t         size)
1786 {
1787     struct rt_serial_device *serial;
1788 
1789     RT_ASSERT(dev != RT_NULL);
1790     if (size == 0) return 0;
1791 
1792     serial = (struct rt_serial_device *)dev;
1793 
1794     if (serial->config.rx_bufsz)
1795     {
1796         return _serial_fifo_rx(dev, pos, buffer, size);
1797     }
1798 
1799     return _serial_poll_rx(dev, pos, buffer, size);
1800 }
1801 
1802 
rt_serial_write(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)1803 static rt_ssize_t rt_serial_write(struct rt_device *dev,
1804                                   rt_off_t          pos,
1805                                   const void       *buffer,
1806                                   rt_size_t         size)
1807 {
1808     struct rt_serial_device  *serial;
1809     struct rt_serial_tx_fifo *tx_fifo;
1810 
1811     RT_ASSERT(dev != RT_NULL);
1812     if (size == 0) return 0;
1813 
1814     serial = (struct rt_serial_device *)dev;
1815     RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL));
1816     tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
1817 
1818     if (serial->config.tx_bufsz == 0)
1819     {
1820         return _serial_poll_tx(dev, pos, buffer, size);
1821     }
1822 
1823     if (dev->open_flag & RT_SERIAL_TX_BLOCKING)
1824     {
1825         RT_ASSERT(tx_fifo != RT_NULL);
1826         if ((tx_fifo->rb.buffer_ptr) == RT_NULL)
1827         {
1828             return _serial_fifo_tx_blocking_nbuf(dev, pos, buffer, size);
1829         }
1830 
1831         return _serial_fifo_tx_blocking_buf(dev, pos, buffer, size);
1832     }
1833 
1834     return _serial_fifo_tx_nonblocking(dev, pos, buffer, size);
1835 }
1836 
1837 const static struct rt_device_ops serial_ops =
1838     {
1839         rt_serial_init,
1840         rt_serial_open,
1841         rt_serial_close,
1842         rt_serial_read,
1843         rt_serial_write,
1844         rt_serial_control};
1845 #endif
1846 
1847 /**
1848   * @brief Register the serial device.
1849   * @param serial RT-thread serial device.
1850   * @param name The device driver's name
1851   * @param flag The capabilities flag of device.
1852   * @param data The device driver's data.
1853   * @return Return the status of the operation.
1854   */
rt_hw_serial_register(struct rt_serial_device * serial,const char * name,rt_uint32_t flag,void * data)1855 rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
1856                                const char              *name,
1857                                rt_uint32_t              flag,
1858                                void                    *data)
1859 {
1860     rt_err_t          ret;
1861     struct rt_device *device;
1862     RT_ASSERT(serial != RT_NULL);
1863 
1864     rt_spin_lock_init(&serial->spinlock);
1865 
1866     device = &serial->parent;
1867 
1868     device->type        = RT_Device_Class_Char;
1869     device->rx_indicate = RT_NULL;
1870     device->tx_complete = RT_NULL;
1871 
1872 #ifdef RT_USING_DEVICE_OPS
1873     device->ops = &serial_ops;
1874 #else
1875     device->init    = rt_serial_init;
1876     device->open    = rt_serial_open;
1877     device->close   = rt_serial_close;
1878     device->read    = RT_NULL;
1879     device->write   = RT_NULL;
1880     device->control = rt_serial_control;
1881 #endif
1882     device->user_data = data;
1883 
1884     /* register a character device */
1885     ret = rt_device_register(device, name, flag);
1886 
1887 #ifdef RT_USING_POSIX_STDIO
1888     /* set fops */
1889     device->fops = &_serial_fops;
1890 #endif
1891     return ret;
1892 }
1893 
1894 /**
1895   * @brief ISR for serial interrupt
1896   * @param serial RT-thread serial device.
1897   * @param event ISR event type.
1898   */
rt_hw_serial_control_isr(struct rt_serial_device * serial,int cmd,void * args)1899 rt_err_t rt_hw_serial_control_isr(struct rt_serial_device *serial, int cmd, void *args)
1900 {
1901     RT_ASSERT(serial != RT_NULL);
1902     rt_err_t ret = RT_EOK;
1903 
1904     switch (cmd)
1905     {
1906     case RT_HW_SERIAL_CTRL_PUTC:
1907         if (args == RT_NULL)
1908         {
1909             ret = -RT_EINVAL;
1910         }
1911         else
1912         {
1913             struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
1914             rx_fifo                           = (struct rt_serial_rx_fifo *)serial->serial_rx;
1915             RT_ASSERT(rx_fifo != RT_NULL);
1916 
1917 #ifdef RT_SERIAL_BUF_STRATEGY_DROP
1918             rt_ringbuffer_putchar(&rx_fifo->rb, *(rt_uint8_t *)args);
1919 #else
1920             rt_ringbuffer_putchar_force(&rx_fifo->rb, *(rt_uint8_t *)args);
1921 #endif /* RT_SERIAL_BUF_STRATEGY_DROP */
1922         }
1923         break;
1924 
1925     case RT_HW_SERIAL_CTRL_GETC:
1926         if (args == RT_NULL)
1927         {
1928             ret = -RT_EINVAL;
1929         }
1930         else
1931         {
1932             struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
1933             tx_fifo                           = (struct rt_serial_tx_fifo *)serial->serial_tx;
1934             RT_ASSERT(tx_fifo != RT_NULL);
1935             if (rt_ringbuffer_getchar(&tx_fifo->rb, (rt_uint8_t *)args) == 0)
1936             {
1937                 ret = -RT_EEMPTY;
1938             }
1939         }
1940         break;
1941 
1942 #ifdef RT_SERIAL_USING_DMA
1943     case RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF:
1944         if (args == RT_NULL)
1945         {
1946             ret = -RT_EINVAL;
1947         }
1948         else
1949         {
1950             struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
1951             rx_fifo                           = (struct rt_serial_rx_fifo *)serial->serial_rx;
1952             RT_ASSERT(rx_fifo != RT_NULL);
1953             *(rt_uint8_t **)args = rx_fifo->dma_ping_rb.buffer_ptr;
1954         }
1955         break;
1956 #endif
1957 
1958     default:
1959         ret = -RT_EINVAL;
1960         break;
1961     }
1962 
1963     return ret;
1964 }
1965 
1966 /**
1967   * @brief ISR for serial interrupt
1968   * @param serial RT-thread serial device.
1969   * @param event ISR event type.
1970   */
rt_hw_serial_isr(struct rt_serial_device * serial,int event)1971 void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
1972 {
1973     RT_ASSERT(serial != RT_NULL);
1974 
1975     switch (event & 0xff)
1976     {
1977     /* Interrupt receive event */
1978     case RT_SERIAL_EVENT_RX_IND:
1979     case RT_SERIAL_EVENT_RX_DMADONE: {
1980         struct rt_serial_rx_fifo *rx_fifo;
1981         rt_size_t                 rx_length;
1982         rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
1983         RT_ASSERT(rx_fifo != RT_NULL);
1984 
1985 #ifdef RT_SERIAL_USING_DMA
1986         rt_base_t level;
1987         /* If the event is RT_SERIAL_EVENT_RX_IND, rx_length is equal to 0 */
1988         rx_length = event >> 8;
1989 
1990         /* RT_SERIAL_EVENT_RX_DMADONE MODE */
1991         if (rx_length != 0)
1992         {
1993 #ifdef RT_SERIAL_BUF_STRATEGY_DROP
1994             rt_uint8_t *ptr;
1995             rt_size_t   size;
1996             rt_size_t   put_len;
1997             /* UART_IT_IDLE and dma isr */
1998             level = rt_spin_lock_irqsave(&serial->spinlock);
1999             do
2000             {
2001                 rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
2002 
2003                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
2004 
2005                 put_len = rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
2006                 if (put_len != size)
2007                     break;
2008 
2009                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
2010                 if (size == 0)
2011                     break;
2012 
2013                 rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
2014             } while (0);
2015             rt_spin_unlock_irqrestore(&serial->spinlock, level);
2016 #else
2017             rt_uint8_t *ptr;
2018             rt_size_t   size;
2019             /* UART_IT_IDLE and dma isr */
2020             level = rt_spin_lock_irqsave(&serial->spinlock);
2021             do
2022             {
2023                 rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
2024 
2025                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
2026 
2027                 rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size);
2028 
2029                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
2030                 if (size == 0)
2031                     break;
2032 
2033                 rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size);
2034             } while (0);
2035             rt_spin_unlock_irqrestore(&serial->spinlock, level);
2036 #endif /* RT_SERIAL_BUF_STRATEGY_DROP */
2037         }
2038 #endif /* RT_SERIAL_USING_DMA */
2039 
2040         rx_length = rt_ringbuffer_data_len(&rx_fifo->rb);
2041         if (rx_length == 0)
2042         {
2043             break;
2044         }
2045 
2046         if (serial->parent.open_flag & RT_SERIAL_RX_BLOCKING)
2047         {
2048             if (rx_fifo->rx_cpt_index && rx_length >= rx_fifo->rx_cpt_index)
2049             {
2050                 rx_fifo->rx_cpt_index = 0;
2051                 rt_completion_done(&rx_fifo->rx_cpt);
2052             }
2053         }
2054 
2055         /* Trigger the receiving completion callback */
2056         if (serial->parent.rx_indicate != RT_NULL)
2057         {
2058             serial->parent.rx_indicate(&serial->parent, rx_length);
2059         }
2060 
2061         if (serial->rx_notify.notify != RT_NULL)
2062         {
2063             serial->rx_notify.notify(serial->rx_notify.dev);
2064         }
2065         break;
2066     }
2067 
2068     /* Interrupt transmit event */
2069     case RT_SERIAL_EVENT_TX_DONE: {
2070         struct rt_serial_tx_fifo *tx_fifo;
2071         rt_size_t                 tx_length;
2072         rt_ssize_t                transmit_size;
2073         tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
2074         RT_ASSERT(tx_fifo != RT_NULL);
2075 
2076         /* Get the length of the data from the ringbuffer */
2077         tx_length = rt_ringbuffer_data_len(&tx_fifo->rb);
2078 
2079         /* If there is no data in tx_ringbuffer,
2080          * then the transmit completion callback is triggered*/
2081         if (tx_length == 0)
2082         {
2083             rt_completion_done(&tx_fifo->tx_cpt);
2084 
2085             /* Trigger the transmit completion callback */
2086             if (serial->parent.tx_complete != RT_NULL)
2087             {
2088                 serial->parent.tx_complete(&serial->parent, RT_NULL);
2089             }
2090 
2091             rt_atomic_flag_clear(&tx_fifo->activated);
2092             break;
2093         }
2094 
2095         rt_atomic_flag_test_and_set(&tx_fifo->activated);
2096         /* Call the transmit interface for transmission again */
2097         /* Note that in interrupt mode, tx_fifo->buffer and tx_length
2098          * are inactive parameters */
2099         transmit_size = serial->ops->transmit(serial,
2100                                               tx_fifo->rb.buffer_ptr,
2101                                               tx_length,
2102                                               serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
2103         if (transmit_size <= 0)
2104         {
2105             rt_atomic_flag_clear(&tx_fifo->activated);
2106         }
2107         break;
2108     }
2109 
2110 #ifdef RT_SERIAL_USING_DMA
2111     case RT_SERIAL_EVENT_TX_DMADONE: {
2112         struct rt_serial_tx_fifo *tx_fifo;
2113         rt_size_t                 tx_length;
2114         rt_ssize_t                transmit_size;
2115         tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
2116         RT_ASSERT(tx_fifo != RT_NULL);
2117         /* nonblock */
2118         if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING)
2119         {
2120             /* Each interruption upon entry indicates that the previous `put_size` has already been sent completely */
2121             rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size);
2122 
2123             /* Get the length of the data from the ringbuffer */
2124             tx_length = rt_ringbuffer_data_len(&tx_fifo->rb);
2125 
2126             if (tx_length != 0)
2127             {
2128                 /* If there is some data in tx_ringbuffer,
2129                  * then call the transmit interface for transmission again */
2130                 rt_atomic_flag_test_and_set(&tx_fifo->activated);
2131 
2132                 rt_uint8_t *put_ptr;
2133                 /* Get the linear length buffer from ringbuffer */
2134                 tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr);
2135 
2136                 /* Call the transmit interface for transmission again */
2137                 transmit_size = serial->ops->transmit(serial,
2138                                                       put_ptr,
2139                                                       tx_fifo->put_size,
2140                                                       RT_SERIAL_TX_NON_BLOCKING);
2141                 if (transmit_size <= 0)
2142                 {
2143                     rt_atomic_flag_clear(&tx_fifo->activated);
2144                 }
2145                 break;
2146             }
2147         }
2148 
2149         rt_completion_done(&tx_fifo->tx_cpt);
2150 
2151         /* Trigger the transmit completion callback */
2152         if (serial->parent.tx_complete != RT_NULL)
2153         {
2154             serial->parent.tx_complete(&serial->parent, RT_NULL);
2155         }
2156 
2157         rt_atomic_flag_clear(&tx_fifo->activated);
2158         break;
2159     }
2160 #endif /* RT_SERIAL_USING_DMA */
2161     default:
2162         break;
2163     }
2164 }
2165