summaryrefslogtreecommitdiff
path: root/docs/en/demo/usbh_serial.rst
blob: 03d89f0461a06c1e02cb898173bb89292525a81b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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.

.. figure:: img/usbh_serial.png

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:

.. code-block:: C

    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.

.. code-block:: C

    [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