1 /*
2  * Copyright (c) 2025, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <rtthread.h>
7 #include <rtdevice.h>
8 
9 #include "usbh_core.h"
10 #include "usbh_cdc_acm.h"
11 #include "usbh_ftdi.h"
12 #include "usbh_cp210x.h"
13 #include "usbh_ch34x.h"
14 #include "usbh_pl2303.h"
15 
16 #define DEV_FORMAT_VENDOR  "ttyUSB%d"
17 #define DEV_FORMAT_CDC_ACM "ttyACM%d"
18 
19 #define USBH_RX_MAX_SIZE 2048
20 
21 #ifndef CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS
22 #define CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS (4)
23 #endif
24 
25 #ifndef CONFIG_USBHOST_SERIAL_RX_BUFSIZE
26 #define CONFIG_USBHOST_SERIAL_RX_BUFSIZE (USBH_RX_MAX_SIZE * 2)
27 #endif
28 
29 enum usbh_serial_type {
30     USBH_SERIAL_TYPE_CDC_ACM = 0,
31     USBH_SERIAL_TYPE_FTDI,
32     USBH_SERIAL_TYPE_CP210X,
33     USBH_SERIAL_TYPE_CH34X,
34     USBH_SERIAL_TYPE_PL2303,
35 };
36 
37 struct usbh_serial {
38     struct rt_device parent;
39     enum usbh_serial_type type;
40     uint8_t minor;
41     char name[CONFIG_USBHOST_DEV_NAMELEN];
42     struct rt_ringbuffer rx_rb;
43     rt_uint8_t rx_rb_buffer[CONFIG_USBHOST_SERIAL_RX_BUFSIZE];
44 };
45 
46 static uint32_t g_devinuse_vendor = 0;
47 static uint32_t g_devinuse_cdc_acm = 0;
48 
49 static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_vendor_rx_buf[CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
50 static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_cdc_acm_rx_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
51 
usbh_serial_alloc(uint8_t type)52 static struct usbh_serial *usbh_serial_alloc(uint8_t type)
53 {
54     uint8_t devno;
55     struct usbh_serial *serial;
56 
57     for (devno = 0; devno < CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS; devno++) {
58         if ((g_devinuse_vendor & (1U << devno)) == 0) {
59             g_devinuse_vendor |= (1U << devno);
60 
61             serial = rt_malloc(sizeof(struct usbh_serial));
62             memset(serial, 0, sizeof(struct usbh_serial));
63             serial->type = type;
64             serial->minor = devno;
65             snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor);
66             return serial;
67         }
68     }
69     return NULL;
70 }
71 
usbh_serial_free(struct usbh_serial * serial)72 static void usbh_serial_free(struct usbh_serial *serial)
73 {
74     uint8_t devno = serial->minor;
75 
76     if (devno < 32) {
77         g_devinuse_vendor &= ~(1U << devno);
78     }
79     memset(serial, 0, sizeof(struct usbh_serial));
80     rt_free(serial);
81 }
82 
usbh_serial_cdc_acm_alloc(uint8_t type)83 static struct usbh_serial *usbh_serial_cdc_acm_alloc(uint8_t type)
84 {
85     uint8_t devno;
86     struct usbh_serial *serial;
87 
88     for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
89         if ((g_devinuse_cdc_acm & (1U << devno)) == 0) {
90             g_devinuse_cdc_acm |= (1U << devno);
91 
92             serial = rt_malloc(sizeof(struct usbh_serial));
93             memset(serial, 0, sizeof(struct usbh_serial));
94             serial->type = type;
95             serial->minor = devno;
96             snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor);
97             return serial;
98         }
99     }
100     return NULL;
101 }
102 
usbh_serial_cdc_acm_free(struct usbh_serial * serial)103 static void usbh_serial_cdc_acm_free(struct usbh_serial *serial)
104 {
105     uint8_t devno = serial->minor;
106 
107     if (devno < 32) {
108         g_devinuse_cdc_acm &= ~(1U << devno);
109     }
110     memset(serial, 0, sizeof(struct usbh_serial));
111     rt_free(serial);
112 }
113 
usbh_serial_open(struct rt_device * dev,rt_uint16_t oflag)114 static rt_err_t usbh_serial_open(struct rt_device *dev, rt_uint16_t oflag)
115 {
116     struct usbh_serial *serial;
117 
118     RT_ASSERT(dev != RT_NULL);
119 
120     serial = (struct usbh_serial *)dev;
121 
122     switch (serial->type) {
123         case USBH_SERIAL_TYPE_CDC_ACM:
124             break;
125         case USBH_SERIAL_TYPE_FTDI:
126             break;
127         case USBH_SERIAL_TYPE_CP210X:
128             break;
129         case USBH_SERIAL_TYPE_CH34X:
130             break;
131         case USBH_SERIAL_TYPE_PL2303:
132             break;
133 
134         default:
135             break;
136     }
137 
138     return RT_EOK;
139 }
140 
usbh_serial_close(struct rt_device * dev)141 static rt_err_t usbh_serial_close(struct rt_device *dev)
142 {
143     struct usbh_serial *serial;
144 
145     RT_ASSERT(dev != RT_NULL);
146 
147     serial = (struct usbh_serial *)dev;
148 
149     switch (serial->type) {
150         case USBH_SERIAL_TYPE_CDC_ACM:
151             break;
152         case USBH_SERIAL_TYPE_FTDI:
153             break;
154         case USBH_SERIAL_TYPE_CP210X:
155             break;
156         case USBH_SERIAL_TYPE_CH34X:
157             break;
158         case USBH_SERIAL_TYPE_PL2303:
159             break;
160 
161         default:
162             break;
163     }
164 
165     return RT_EOK;
166 }
167 
usbh_serial_read(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)168 static rt_ssize_t usbh_serial_read(struct rt_device *dev,
169                                    rt_off_t pos,
170                                    void *buffer,
171                                    rt_size_t size)
172 {
173     struct usbh_serial *serial;
174 
175     RT_ASSERT(dev != RT_NULL);
176 
177     serial = (struct usbh_serial *)dev;
178 
179     return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size);
180 }
181 
usbh_serial_write(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)182 static rt_ssize_t usbh_serial_write(struct rt_device *dev,
183                                     rt_off_t pos,
184                                     const void *buffer,
185                                     rt_size_t size)
186 {
187     struct usbh_serial *serial;
188     int ret = 0;
189     rt_uint8_t *align_buf;
190 
191     RT_ASSERT(dev != RT_NULL);
192 
193     serial = (struct usbh_serial *)dev;
194 
195     align_buf = (rt_uint8_t *)buffer;
196 #ifdef CONFIG_USB_DCACHE_ENABLE
197     if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
198         align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
199         if (!align_buf) {
200             USB_LOG_ERR("serial get align buf failed\n");
201             return 0;
202         }
203 
204         usb_memcpy(align_buf, buffer, size);
205     }
206 #endif
207 
208     switch (serial->type) {
209 #if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
210         case USBH_SERIAL_TYPE_CDC_ACM:
211             ret = usbh_cdc_acm_bulk_out_transfer((struct usbh_cdc_acm *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
212             if (ret < 0) {
213                 USB_LOG_ERR("usbh_cdc_acm_bulk_out_transfer failed: %d\n", ret);
214 #ifdef CONFIG_USB_DCACHE_ENABLE
215                 rt_free_align(align_buf);
216 #endif
217                 return 0;
218             }
219             break;
220 #endif
221 #if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
222         case USBH_SERIAL_TYPE_FTDI:
223             ret = usbh_ftdi_bulk_out_transfer((struct usbh_ftdi *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
224             if (ret < 0) {
225                 USB_LOG_ERR("usbh_ftdi_bulk_out_transfer failed: %d\n", ret);
226 #ifdef CONFIG_USB_DCACHE_ENABLE
227                 rt_free_align(align_buf);
228 #endif
229                 return 0;
230             }
231             break;
232 #endif
233 #if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
234         case USBH_SERIAL_TYPE_CH34X:
235             ret = usbh_ch34x_bulk_out_transfer((struct usbh_ch34x *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
236             if (ret < 0) {
237                 USB_LOG_ERR("usbh_ch34x_bulk_out_transfer failed: %d\n", ret);
238 #ifdef CONFIG_USB_DCACHE_ENABLE
239                 rt_free_align(align_buf);
240 #endif
241                 return 0;
242             }
243             break;
244 #endif
245 #if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
246         case USBH_SERIAL_TYPE_PL2303:
247             ret = usbh_pl2303_bulk_out_transfer((struct usbh_pl2303 *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
248             if (ret < 0) {
249                 USB_LOG_ERR("usbh_pl2303_bulk_out_transfer failed: %d\n", ret);
250 #ifdef CONFIG_USB_DCACHE_ENABLE
251                 rt_free_align(align_buf);
252 #endif
253                 return 0;
254             }
255             break;
256 #endif
257         default:
258             break;
259     }
260 
261 #ifdef CONFIG_USB_DCACHE_ENABLE
262     if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
263         rt_free_align(align_buf);
264     }
265 #endif
266 
267     return ret;
268 }
269 
usbh_serial_control(struct rt_device * dev,int cmd,void * args)270 static rt_err_t usbh_serial_control(struct rt_device *dev,
271                                     int cmd,
272                                     void *args)
273 {
274     struct usbh_serial *serial;
275     struct serial_configure *config;
276     struct cdc_line_coding line_coding;
277     int ret = -RT_EINVAL;
278 
279     RT_ASSERT(dev != RT_NULL);
280 
281     serial = (struct usbh_serial *)dev;
282 
283     switch (serial->type) {
284 #if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
285         case USBH_SERIAL_TYPE_CDC_ACM:
286             if (cmd == RT_DEVICE_CTRL_CONFIG) {
287                 struct usbh_cdc_acm *cdc_acm_class;
288                 cdc_acm_class = (struct usbh_cdc_acm *)dev->user_data;
289 
290                 config = (struct serial_configure *)args;
291 
292                 line_coding.dwDTERate = config->baud_rate;
293                 line_coding.bDataBits = config->data_bits;
294                 line_coding.bCharFormat = 0; // STOP_BITS_1
295                 line_coding.bParityType = config->parity;
296 
297                 usbh_cdc_acm_set_line_coding(cdc_acm_class, &line_coding);
298             }
299 
300             ret = RT_EOK;
301             break;
302 #endif
303 #if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
304         case USBH_SERIAL_TYPE_FTDI:
305             if (cmd == RT_DEVICE_CTRL_CONFIG) {
306                 struct usbh_ftdi *ftdi_class;
307                 ftdi_class = (struct usbh_ftdi *)dev->user_data;
308 
309                 config = (struct serial_configure *)args;
310 
311                 line_coding.dwDTERate = config->baud_rate;
312                 line_coding.bDataBits = config->data_bits;
313                 line_coding.bCharFormat = 0; // STOP_BITS_1
314                 line_coding.bParityType = config->parity;
315 
316                 usbh_ftdi_set_line_coding(ftdi_class, &line_coding);
317             }
318 
319             ret = RT_EOK;
320             break;
321 #endif
322 #if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
323         case USBH_SERIAL_TYPE_CP210X:
324             if (cmd == RT_DEVICE_CTRL_CONFIG) {
325                 struct usbh_cp210x *cp210x_class;
326                 cp210x_class = (struct usbh_cp210x *)dev->user_data;
327 
328                 config = (struct serial_configure *)args;
329 
330                 line_coding.dwDTERate = config->baud_rate;
331                 line_coding.bDataBits = config->data_bits;
332                 line_coding.bCharFormat = 0; // STOP_BITS_1
333                 line_coding.bParityType = config->parity;
334 
335                 usbh_cp210x_set_line_coding(cp210x_class, &line_coding);
336             }
337 
338             ret = RT_EOK;
339             break;
340 #endif
341 #if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
342         case USBH_SERIAL_TYPE_CH34X:
343             if (cmd == RT_DEVICE_CTRL_CONFIG) {
344                 struct usbh_ch34x *ch34x_class;
345                 ch34x_class = (struct usbh_ch34x *)dev->user_data;
346 
347                 config = (struct serial_configure *)args;
348 
349                 line_coding.dwDTERate = config->baud_rate;
350                 line_coding.bDataBits = config->data_bits;
351                 line_coding.bCharFormat = 0; // STOP_BITS_1
352                 line_coding.bParityType = config->parity;
353 
354                 usbh_ch34x_set_line_coding(ch34x_class, &line_coding);
355             }
356 
357             ret = RT_EOK;
358             break;
359 #endif
360 #if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
361         case USBH_SERIAL_TYPE_PL2303:
362             if (cmd == RT_DEVICE_CTRL_CONFIG) {
363                 struct usbh_pl2303 *pl2303_class;
364                 pl2303_class = (struct usbh_pl2303 *)dev->user_data;
365 
366                 config = (struct serial_configure *)args;
367 
368                 line_coding.dwDTERate = config->baud_rate;
369                 line_coding.bDataBits = config->data_bits;
370                 line_coding.bCharFormat = 0; // STOP_BITS_1
371                 line_coding.bParityType = config->parity;
372 
373                 usbh_pl2303_set_line_coding(pl2303_class, &line_coding);
374             }
375 
376             ret = RT_EOK;
377             break;
378 #endif
379         default:
380             break;
381     }
382 
383     return ret;
384 }
385 
386 #ifdef RT_USING_DEVICE_OPS
387 const static struct rt_device_ops usbh_serial_ops = {
388     NULL,
389     usbh_serial_open,
390     usbh_serial_close,
391     usbh_serial_read,
392     usbh_serial_write,
393     usbh_serial_control
394 };
395 #endif
396 
397 #ifdef RT_USING_POSIX_DEVIO
398 #include <unistd.h>
399 #include <fcntl.h>
400 #include <poll.h>
401 #include <sys/ioctl.h>
402 #include <dfs_file.h>
403 
404 #ifdef RT_USING_POSIX_TERMIOS
405 #include <termios.h>
406 #endif
407 
usbh_serial_fops_rx_ind(rt_device_t dev,rt_size_t size)408 static rt_err_t usbh_serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
409 {
410     rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
411 
412     return RT_EOK;
413 }
414 
415 /* fops for serial */
usbh_serial_fops_open(struct dfs_file * fd)416 static int usbh_serial_fops_open(struct dfs_file *fd)
417 {
418     rt_err_t ret = 0;
419     rt_uint16_t flags = 0;
420     rt_device_t device;
421 
422     device = (rt_device_t)fd->vnode->data;
423     RT_ASSERT(device != RT_NULL);
424 
425     switch (fd->flags & O_ACCMODE)
426     {
427     case O_RDONLY:
428         USB_LOG_DBG("fops open: O_RDONLY!");
429         flags = RT_DEVICE_FLAG_RDONLY;
430         break;
431     case O_WRONLY:
432         USB_LOG_DBG("fops open: O_WRONLY!");
433         flags = RT_DEVICE_FLAG_WRONLY;
434         break;
435     case O_RDWR:
436         USB_LOG_DBG("fops open: O_RDWR!");
437         flags = RT_DEVICE_FLAG_RDWR;
438         break;
439     default:
440         USB_LOG_ERR("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
441         break;
442     }
443 
444     if ((fd->flags & O_ACCMODE) != O_WRONLY)
445         rt_device_set_rx_indicate(device, usbh_serial_fops_rx_ind);
446     ret = rt_device_open(device, flags);
447     if (ret == RT_EOK) return 0;
448 
449     return ret;
450 }
451 
usbh_serial_fops_close(struct dfs_file * fd)452 static int usbh_serial_fops_close(struct dfs_file *fd)
453 {
454     rt_device_t device;
455 
456     device = (rt_device_t)fd->vnode->data;
457 
458     rt_device_set_rx_indicate(device, RT_NULL);
459     rt_device_close(device);
460 
461     return 0;
462 }
463 
usbh_serial_fops_ioctl(struct dfs_file * fd,int cmd,void * args)464 static int usbh_serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
465 {
466     rt_device_t device;
467     int flags = (int)(rt_base_t)args;
468     int mask  = O_NONBLOCK | O_APPEND;
469 
470     device = (rt_device_t)fd->vnode->data;
471     switch (cmd)
472     {
473     case FIONREAD:
474         break;
475     case FIONWRITE:
476         break;
477     case F_SETFL:
478         flags &= mask;
479         fd->flags &= ~mask;
480         fd->flags |= flags;
481         break;
482     }
483 
484     return rt_device_control(device, cmd, args);
485 }
486 
usbh_serial_fops_read(struct dfs_file * fd,void * buf,size_t count)487 static int usbh_serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
488 {
489     int size = 0;
490     rt_device_t device;
491 
492     device = (rt_device_t)fd->vnode->data;
493 
494     do
495     {
496         size = rt_device_read(device, -1,  buf, count);
497         if (size <= 0)
498         {
499             if (fd->flags & O_NONBLOCK)
500             {
501                 size = -EAGAIN;
502                 break;
503             }
504 
505             rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER);
506         }
507     }while (size <= 0);
508 
509     return size;
510 }
511 
usbh_serial_fops_write(struct dfs_file * fd,const void * buf,size_t count)512 static int usbh_serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
513 {
514     rt_device_t device;
515 
516     device = (rt_device_t)fd->vnode->data;
517     return rt_device_write(device, -1, buf, count);
518 }
519 
usbh_serial_fops_poll(struct dfs_file * fd,struct rt_pollreq * req)520 static int usbh_serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
521 {
522     int mask = 0;
523     int flags = 0;
524     rt_device_t device;
525     struct usbh_serial *serial;
526 
527     device = (rt_device_t)fd->vnode->data;
528     RT_ASSERT(device != RT_NULL);
529 
530     serial = (struct usbh_serial *)device;
531 
532     /* only support POLLIN */
533     flags = fd->flags & O_ACCMODE;
534     if (flags == O_RDONLY || flags == O_RDWR)
535     {
536         rt_base_t level;
537 
538         rt_poll_add(&(device->wait_queue), req);
539 
540         level = rt_hw_interrupt_disable();
541 
542         if (rt_ringbuffer_data_len(&serial->rx_rb))
543             mask |= POLLIN;
544         rt_hw_interrupt_enable(level);
545     }
546     // mask|=POLLOUT;
547    return mask;
548 }
549 
550 const static struct dfs_file_ops usbh_serial_fops =
551 {
552     usbh_serial_fops_open,
553     usbh_serial_fops_close,
554     usbh_serial_fops_ioctl,
555     usbh_serial_fops_read,
556     usbh_serial_fops_write,
557     RT_NULL, /* flush */
558     RT_NULL, /* lseek */
559     RT_NULL, /* getdents */
560     usbh_serial_fops_poll,
561 };
562 #endif /* RT_USING_POSIX_DEVIO */
563 
usbh_serial_register(struct usbh_serial * serial,void * data)564 rt_err_t usbh_serial_register(struct usbh_serial *serial,
565                               void *data)
566 {
567     rt_err_t ret;
568     struct rt_device *device;
569     RT_ASSERT(serial != RT_NULL);
570 
571     device = &(serial->parent);
572 
573     device->type = RT_Device_Class_Char;
574     device->rx_indicate = RT_NULL;
575     device->tx_complete = RT_NULL;
576 
577 #ifdef RT_USING_DEVICE_OPS
578     device->ops = &usbh_serial_ops;
579 #else
580     device->init = NULL;
581     device->open = usbh_serial_open;
582     device->close = usbh_serial_close;
583     device->read = usbh_serial_read;
584     device->write = usbh_serial_write;
585     device->control = usbh_serial_control;
586 #endif
587     device->user_data = data;
588 
589     /* register a character device */
590     ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
591 
592 #ifdef RT_USING_POSIX_DEVIO
593     /* set fops */
594     device->fops = &usbh_serial_fops;
595 #endif
596     rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer));
597 
598     return ret;
599 }
600 
usbh_serial_unregister(struct usbh_serial * serial)601 void usbh_serial_unregister(struct usbh_serial *serial)
602 {
603     RT_ASSERT(serial != NULL);
604 
605     rt_device_unregister(&serial->parent);
606 
607     if (serial->type == USBH_SERIAL_TYPE_CDC_ACM) {
608         usbh_serial_cdc_acm_free(serial);
609     } else {
610         usbh_serial_free(serial);
611     }
612 }
613 
614 #if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
usbh_cdc_acm_callback(void * arg,int nbytes)615 void usbh_cdc_acm_callback(void *arg, int nbytes)
616 {
617     struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
618     struct usbh_serial *serial;
619     int ret;
620     struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
621 
622     if (nbytes > 0) {
623         serial = (struct usbh_serial *)cdc_acm_class->user_data;
624         rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_cdc_acm_rx_buf[serial->minor], nbytes);
625 
626         if (serial->parent.rx_indicate) {
627             serial->parent.rx_indicate(&serial->parent, nbytes);
628         }
629 
630         usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
631         ret = usbh_submit_urb(urb);
632         if (ret < 0) {
633             USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
634         }
635     }
636 }
637 
usbh_cdc_acm_run(struct usbh_cdc_acm * cdc_acm_class)638 void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
639 {
640     struct usbh_serial *serial;
641     int ret;
642     struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
643 
644     serial = usbh_serial_cdc_acm_alloc(USBH_SERIAL_TYPE_CDC_ACM);
645     cdc_acm_class->user_data = serial;
646 
647     usbh_serial_register(serial, cdc_acm_class);
648 
649     struct cdc_line_coding linecoding;
650     linecoding.dwDTERate = 115200;
651     linecoding.bDataBits = 8;
652     linecoding.bParityType = 0;
653     linecoding.bCharFormat = 0;
654     usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding);
655 
656     usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
657     ret = usbh_submit_urb(urb);
658     if (ret < 0) {
659         USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
660         usbh_serial_unregister(serial);
661         return;
662     }
663 }
664 
usbh_cdc_acm_stop(struct usbh_cdc_acm * cdc_acm_class)665 void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
666 {
667     struct usbh_serial *serial;
668 
669     serial = (struct usbh_serial *)cdc_acm_class->user_data;
670     usbh_serial_unregister(serial);
671 }
672 #endif
673 
674 #if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
usbh_ftdi_callback(void * arg,int nbytes)675 void usbh_ftdi_callback(void *arg, int nbytes)
676 {
677     struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)arg;
678     struct usbh_serial *serial;
679     int ret;
680     struct usbh_urb *urb = &ftdi_class->bulkin_urb;
681 
682     if (nbytes >= 2) {
683         serial = (struct usbh_serial *)ftdi_class->user_data;
684 
685         nbytes -= 2; // Skip the first two bytes (header)
686         rt_ringbuffer_put(&serial->rx_rb, &g_usbh_serial_vendor_rx_buf[serial->minor][2], nbytes);
687 
688         if (serial->parent.rx_indicate && nbytes) {
689             serial->parent.rx_indicate(&serial->parent, nbytes);
690         }
691 
692         usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
693         ret = usbh_submit_urb(urb);
694         if (ret < 0) {
695             USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
696         }
697     }
698 }
699 
usbh_ftdi_run(struct usbh_ftdi * ftdi_class)700 void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
701 {
702     struct usbh_serial *serial;
703     int ret;
704     struct usbh_urb *urb = &ftdi_class->bulkin_urb;
705 
706     serial = usbh_serial_alloc(USBH_SERIAL_TYPE_FTDI);
707     ftdi_class->user_data = serial;
708 
709     usbh_serial_register(serial, ftdi_class);
710 
711     struct cdc_line_coding linecoding;
712     linecoding.dwDTERate = 115200;
713     linecoding.bDataBits = 8;
714     linecoding.bParityType = 0;
715     linecoding.bCharFormat = 0;
716     usbh_ftdi_set_line_coding(ftdi_class, &linecoding);
717 
718     usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
719     ret = usbh_submit_urb(urb);
720     if (ret < 0) {
721         USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
722         usbh_serial_unregister(serial);
723         return;
724     }
725 }
726 
usbh_ftdi_stop(struct usbh_ftdi * ftdi_class)727 void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
728 {
729     struct usbh_serial *serial;
730 
731     serial = (struct usbh_serial *)ftdi_class->user_data;
732     usbh_serial_unregister(serial);
733 }
734 #endif
735 
736 #if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
usbh_ch34x_callback(void * arg,int nbytes)737 void usbh_ch34x_callback(void *arg, int nbytes)
738 {
739     struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)arg;
740     struct usbh_serial *serial;
741     int ret;
742     struct usbh_urb *urb = &ch34x_class->bulkin_urb;
743 
744     if (nbytes > 0) {
745         serial = (struct usbh_serial *)ch34x_class->user_data;
746         rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
747 
748         if (serial->parent.rx_indicate) {
749             serial->parent.rx_indicate(&serial->parent, nbytes);
750         }
751 
752         usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
753         ret = usbh_submit_urb(urb);
754         if (ret < 0) {
755             USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
756         }
757     }
758 }
759 
usbh_ch34x_run(struct usbh_ch34x * ch34x_class)760 void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
761 {
762     struct usbh_serial *serial;
763     int ret;
764     struct usbh_urb *urb = &ch34x_class->bulkin_urb;
765 
766     serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CH34X);
767     ch34x_class->user_data = serial;
768 
769     usbh_serial_register(serial, ch34x_class);
770 
771     struct cdc_line_coding linecoding;
772     linecoding.dwDTERate = 115200;
773     linecoding.bDataBits = 8;
774     linecoding.bParityType = 0;
775     linecoding.bCharFormat = 0;
776     usbh_ch34x_set_line_coding(ch34x_class, &linecoding);
777 
778     usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
779     ret = usbh_submit_urb(urb);
780     if (ret < 0) {
781         USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
782         usbh_serial_unregister(serial);
783         return;
784     }
785 }
786 
usbh_ch34x_stop(struct usbh_ch34x * ch34x_class)787 void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
788 {
789     struct usbh_serial *serial;
790 
791     serial = (struct usbh_serial *)ch34x_class->user_data;
792     usbh_serial_unregister(serial);
793 }
794 #endif
795 
796 #if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
usbh_cp210x_callback(void * arg,int nbytes)797 void usbh_cp210x_callback(void *arg, int nbytes)
798 {
799     struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)arg;
800     struct usbh_serial *serial;
801     int ret;
802     struct usbh_urb *urb = &cp210x_class->bulkin_urb;
803 
804     if (nbytes > 0) {
805         serial = (struct usbh_serial *)cp210x_class->user_data;
806         rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
807 
808         if (serial->parent.rx_indicate) {
809             serial->parent.rx_indicate(&serial->parent, nbytes);
810         }
811 
812         usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
813         ret = usbh_submit_urb(urb);
814         if (ret < 0) {
815             USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
816         }
817     }
818 }
819 
usbh_cp210x_run(struct usbh_cp210x * cp210x_class)820 void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
821 {
822     struct usbh_serial *serial;
823     int ret;
824     struct usbh_urb *urb = &cp210x_class->bulkin_urb;
825 
826     serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CP210X);
827     cp210x_class->user_data = serial;
828 
829     usbh_serial_register(serial, cp210x_class);
830 
831     struct cdc_line_coding linecoding;
832     linecoding.dwDTERate = 115200;
833     linecoding.bDataBits = 8;
834     linecoding.bParityType = 0;
835     linecoding.bCharFormat = 0;
836     usbh_cp210x_set_line_coding(cp210x_class, &linecoding);
837 
838     usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
839     ret = usbh_submit_urb(urb);
840     if (ret < 0) {
841         USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
842         usbh_serial_unregister(serial);
843         return;
844     }
845 }
846 
usbh_cp210x_stop(struct usbh_cp210x * cp210x_class)847 void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
848 {
849     struct usbh_serial *serial;
850 
851     serial = (struct usbh_serial *)cp210x_class->user_data;
852     usbh_serial_unregister(serial);
853 }
854 #endif
855 
856 #if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
usbh_pl2303_callback(void * arg,int nbytes)857 void usbh_pl2303_callback(void *arg, int nbytes)
858 {
859     struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)arg;
860     struct usbh_serial *serial;
861     int ret;
862     struct usbh_urb *urb = &pl2303_class->bulkin_urb;
863 
864     if (nbytes > 0) {
865         serial = (struct usbh_serial *)pl2303_class->user_data;
866         rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
867 
868         if (serial->parent.rx_indicate) {
869             serial->parent.rx_indicate(&serial->parent, nbytes);
870         }
871 
872         usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
873         ret = usbh_submit_urb(urb);
874         if (ret < 0) {
875             USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
876         }
877     }
878 }
879 
usbh_pl2303_run(struct usbh_pl2303 * pl2303_class)880 void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
881 {
882     struct usbh_serial *serial;
883     int ret;
884     struct usbh_urb *urb = &pl2303_class->bulkin_urb;
885 
886     serial = usbh_serial_alloc(USBH_SERIAL_TYPE_PL2303);
887     pl2303_class->user_data = serial;
888 
889     usbh_serial_register(serial, pl2303_class);
890 
891     struct cdc_line_coding linecoding;
892     linecoding.dwDTERate = 115200;
893     linecoding.bDataBits = 8;
894     linecoding.bParityType = 0;
895     linecoding.bCharFormat = 0;
896     usbh_pl2303_set_line_coding(pl2303_class, &linecoding);
897 
898     usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
899     ret = usbh_submit_urb(urb);
900     if (ret < 0) {
901         USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
902         usbh_serial_unregister(serial);
903         return;
904     }
905 }
906 
usbh_pl2303_stop(struct usbh_pl2303 * pl2303_class)907 void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
908 {
909     struct usbh_serial *serial;
910 
911     serial = (struct usbh_serial *)pl2303_class->user_data;
912     usbh_serial_unregister(serial);
913 }
914 #endif
915