Serial Host
This section mainly introduces the usage of the Host serial framework. The Serial framework currently supports CDC ACM, FTDI, CP210x, CH34x, PL2303, and GSM drivers.
Currently supports two usage methods: one is using native CherryUSB usbhost serial API for operations, and the other is based on platform-wrapped APIs such as RT-Thread device API and NuttX POSIX API.
The following demonstrates using CherryUSB usbhost serial API for serial loopback testing with blocking transmission and asynchronous reception:
struct usbh_serial *serial;
serial = usbh_serial_open("/dev/ttyACM0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
if (serial == NULL) {
serial = usbh_serial_open("/dev/ttyUSB0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
if (serial == NULL) {
USB_LOG_RAW("no serial device found\r\n");
goto delete;
}
}
struct usbh_serial_termios termios;
memset(&termios, 0, sizeof(termios));
termios.baudrate = 115200;
termios.stopbits = 0;
termios.parity = 0;
termios.databits = 8;
termios.rtscts = false;
termios.rx_timeout = 0;
ret = usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
if (ret < 0) {
USB_LOG_RAW("set serial attr error, ret:%d\r\n", ret);
goto delete_with_close;
}
serial_tx_bytes = 0;
while (1) {
ret = usbh_serial_write(serial, serial_tx_buffer, sizeof(serial_tx_buffer));
if (ret < 0) {
USB_LOG_RAW("serial write error, ret:%d\r\n", ret);
goto delete_with_close;
} else {
serial_tx_bytes += ret;
if (serial_tx_bytes == SERIAL_TEST_LEN) {
USB_LOG_RAW("send over\r\n");
break;
}
}
}
volatile uint32_t wait_timeout = 0;
serial_rx_bytes = 0;
while (1) {
ret = usbh_serial_read(serial, &serial_rx_data[serial_rx_bytes], SERIAL_TEST_LEN - serial_rx_bytes);
if (ret < 0) {
USB_LOG_RAW("serial read error, ret:%d\r\n", ret);
goto delete_with_close;
} else {
serial_rx_bytes += ret;
if (serial_rx_bytes == SERIAL_TEST_LEN) {
USB_LOG_RAW("receive over\r\n");
for (uint32_t i = 0; i < SERIAL_TEST_LEN; i++) {
if (serial_rx_data[i] != 0xa5) {
USB_LOG_RAW("serial loopback data error at index %d, data: 0x%02x\r\n", (unsigned int)i, serial_rx_data[i]);
goto delete_with_close;
}
}
serial_test_success = true;
break;
}
}
wait_timeout++;
if (wait_timeout > 500) { // 5s
USB_LOG_RAW("serial read timeout\r\n");
goto delete_with_close;
}
usb_osal_msleep(10);
}
usbh_serial_close(serial);
Caution
Note that the example uses a simple send-then-read approach, so the total length sent cannot exceed CONFIG_USBHOST_SERIAL_RX_SIZE. For normal TX/RX usage, please perform them separately.
Users need to consider the following three scenarios:
USB2TTL device + baud rate enabled (USB2TTL devices must enable baud rate), in this case you need to use usbh_serial_write and usbh_serial_read to send and receive data, and read operations need to be timely to prevent ringbuf data overflow and packet loss. Cannot use usbh_serial_cdc_write_async and usbh_serial_cdc_read_async
Pure USB device + baud rate not started, in this case you can use usbh_serial_cdc_write_async and usbh_serial_cdc_read_async for asynchronous send/receive data. For blocking, you can use usbh_serial_write, but cannot use usbh_serial_read.
Pure USB device + baud rate started, same as 1, but the reception rate will be discounted (because of an extra layer of ringbuf). In this case, usbh_serial_cdc_write_async and usbh_serial_cdc_read_async cannot be used either. If it is a GSM device, please use the first scenario.
Note
Simply put, if receiving data requires going through a ringbuf layer, please use the first scenario.
[I/usbh_hub] New full-speed device on Bus 0, Hub 1, Port 1 connected
[I/usbh_core] New device found,idVendor:10c4,idProduct:ea60,bcdDevice:0100
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 1 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[I/usbh_core] Loading cp210x class driver on interface 0
[I/usbh_cp210x] chip partnum: 0x02
[I/usbh_cp210x] ulAmountInInQueue: 0, ulAmountInOutQueue: 0
[I/usbh_serial] Ep=81 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Ep=01 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyUSB0 (cp210x)
start serial loopback test, len: 1024
send over
receive over
serial loopback test success
[I/usbh_serial] Unregister Serial Class: /dev/ttyUSB0 (cp210x)
[I/usbh_core] Device on Bus 0, Hub 1, Port 1 disconnected
[I/usbh_hub] New high-speed device on Bus 0, Hub 1, Port 1 connected
[I/usbh_core] New device found,idVendor:0403,idProduct:6010,bcdDevice:0700
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 2 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[I/usbh_core] Loading ftdi class driver on interface 0
[I/usbh_ftdi] chip name: FT2232H
[I/usbh_serial] Ep=81 Attr=02 Mps=512 Interval=00 Mult=00
[I/usbh_serial] Ep=02 Attr=02 Mps=512 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyUSB0 (ftdi)
[I/usbh_core] Loading ftdi class driver on interface 1
[I/usbh_ftdi] chip name: FT2232H
[I/usbh_serial] Ep=83 Attr=02 Mps=512 Interval=00 Mult=00
[I/usbh_serial] Ep=04 Attr=02 Mps=512 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyUSB1 (ftdi)
start serial loopback test, len: 1024
send over
receive over
serial loopback test success
[I/usbh_serial] Unregister Serial Class: /dev/ttyUSB0 (ftdi)
[I/usbh_serial] Unregister Serial Class: /dev/ttyUSB1 (ftdi)
[I/usbh_core] Device on Bus 0, Hub 1, Port 1 disconnected
[I/usbh_hub] New full-speed device on Bus 0, Hub 1, Port 1 connected
[I/usbh_core] New device found,idVendor:067b,idProduct:2303,bcdDevice:0300
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 1 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[I/usbh_core] Loading pl2303 class driver on interface 0
[I/usbh_pl2303] Ep=81 Attr=03 Mps=10 Interval=01 Mult=00
[I/usbh_pl2303] chip type: PL2303HX
[I/usbh_serial] Ep=02 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Ep=83 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyUSB0 (pl2303)
start serial loopback test, len: 1024
send over
receive over
serial loopback test success
[I/usbh_serial] Unregister Serial Class: /dev/ttyUSB0 (pl2303)
[I/usbh_core] Device on Bus 0, Hub 1, Port 1 disconnected
[W/usbh_hub] Failed to enable port 1
[I/usbh_hub] New full-speed device on Bus 0, Hub 1, Port 1 connected
[I/usbh_core] New device found,idVendor:1a86,idProduct:7523,bcdDevice:0264
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 1 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[I/usbh_core] Loading ch34x class driver on interface 0
[I/usbh_ch43x] Ep=81 Attr=03 Mps=8 Interval=01 Mult=00
[I/usbh_ch43x] chip version: 0x31
[I/usbh_serial] Ep=82 Attr=02 Mps=32 Interval=00 Mult=00
[I/usbh_serial] Ep=02 Attr=02 Mps=32 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyUSB0 (ch34x)
start serial loopback test, len: 1024
send over
receive over
serial loopback test success
[I/usbh_serial] Unregister Serial Class: /dev/ttyUSB0 (ch34x)
[I/usbh_core] Device on Bus 0, Hub 1, Port 1 disconnected
[I/usbh_hub] New full-speed device on Bus 0, Hub 1, Port 1 connected
[I/usbh_core] New device found,idVendor:42bf,idProduct:b210,bcdDevice:0217
[I/usbh_core] The device has 1 bNumConfigurations
[I/usbh_core] The device has 3 interfaces
[I/usbh_core] Enumeration success, start loading class driver
[E/usbh_core] Do not support Class:0xff, Subclass:0x01, Protocl:0x00 on interface 0
[I/usbh_core] Loading cdc_acm class driver on interface 1
[I/usbh_cdc_acm] Ep=85 Attr=03 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Ep=04 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Ep=83 Attr=02 Mps=64 Interval=00 Mult=00
[I/usbh_serial] Register Serial Class: /dev/ttyACM0 (cdc_acm)
[I/usbh_core] Loading cdc_data class driver on interface 2
start serial loopback test, len: 1024
send over
receive over
serial loopback test success
[I/usbh_serial] Unregister Serial Class: /dev/ttyACM0 (cdc_acm)
[I/usbh_core] Device on Bus 0, Hub 1, Port 1 disconnected