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