summaryrefslogtreecommitdiff
path: root/docs/source
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2025-12-12 22:45:10 +0800
committersakumisu <[email protected]>2025-12-12 22:45:10 +0800
commitda2263728aba07a28d9b6946b7acb6b0a0a97bb1 (patch)
tree2a53759e9992b54dbf582b8ba111e0c54e1bcf1d /docs/source
parent707e865627e65b9d661a431c92d57e50ab9d20ab (diff)
refactor(serial): add host serial framework
Signed-off-by: sakumisu <[email protected]>
Diffstat (limited to 'docs/source')
-rw-r--r--docs/source/api/api_host.rst105
-rw-r--r--docs/source/demo/usbh_serial.rst94
2 files changed, 196 insertions, 3 deletions
diff --git a/docs/source/api/api_host.rst b/docs/source/api/api_host.rst
index 28287a0b..51b1c502 100644
--- a/docs/source/api/api_host.rst
+++ b/docs/source/api/api_host.rst
@@ -154,14 +154,115 @@ lsusb
int lsusb(int argc, char **argv);
-CDC ACM
+SERIAL
-----------------
+usbh_serial_open
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_open`` 根据路径打开一个串口设备。
+
+.. code-block:: C
+
+ struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags);
+
+- **devname** 串口路径
+- **open_flags** 打开标志,参考 `USBH_SERIAL_OFLAG_*` 定义
+- **return** serial 结构体句柄
+
+usbh_serial_close
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_close`` 关闭串口设备。
+
+.. code-block:: C
+
+ void usbh_serial_close(struct usbh_serial *serial);
+
+- **serial** serial 结构体句柄
+
+usbh_serial_control
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_control`` 对串口进行配置。
+
+.. code-block:: C
+
+ int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg);
+
+- **serial** serial 结构体句柄
+- **cmd** 控制命令,参考 `USBH_SERIAL_CMD_*` 定义
+- **arg** 控制参数指针
+- **return** 0 表示正常其他表示错误
+
+usbh_serial_write
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_write`` 向串口写数据。 **串口设备如果是 USB2TTL 类型,必须按照波特率发送,否则会丢包**
+
+.. code-block:: C
+
+ int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen);
+
+- **serial** serial 结构体句柄
+- **buffer** 数据缓冲区指针
+- **buflen** 要写入的数据长度,如果是 USB2TTL 设备,一次最高 wMaxPacketSize
+- **return** 实际写入的数据长度或者错误码
+
+.. note:: 有无设置波特率都可以使用该 API,当未设置波特率时,长度无限制,如果设置了波特率则为 wMaxPacketSize。
+
+usbh_serial_read
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_read`` 从串口读数据。 **如果没有设置波特率,不允许使用该 API**。
+
+.. code-block:: C
+
+ int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen);
+
+- **serial** serial 结构体句柄
+- **buffer** 数据缓冲区指针
+- **buflen** 要读取的最大数据长度
+- **return** 实际读取的数据长度或者错误码
+
+usbh_serial_cdc_write_async
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_cdc_write_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。
+
+.. code-block:: C
+
+ int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
+
+- **serial** serial 结构体句柄
+- **buffer** 数据缓冲区指针
+- **buflen** 要发送的数据长度
+- **complete** 读数据完成回调函数
+- **arg** 回调函数参数
+- **return** 0 表示正常其他表示错误
+
+usbh_serial_cdc_read_async
+""""""""""""""""""""""""""""""""""""
+
+``usbh_serial_cdc_read_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。
+
+.. code-block:: C
+
+ int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
+
+- **serial** serial 结构体句柄
+- **buffer** 数据缓冲区指针
+- **buflen** 要读取的最大数据长度,一次最高 16K。并且需要是 wMaxPacketSize 的整数倍
+- **complete** 读数据完成回调函数
+- **arg** 回调函数参数
+- **return** 0 表示正常其他表示错误
+
+
HID
-----------------
MSC
-----------------
-RNDIS
+NETWORK
----------------- \ No newline at end of file
diff --git a/docs/source/demo/usbh_serial.rst b/docs/source/demo/usbh_serial.rst
index 58355cfe..c3c99255 100644
--- a/docs/source/demo/usbh_serial.rst
+++ b/docs/source/demo/usbh_serial.rst
@@ -1,4 +1,96 @@
usbh_serial
===============
-当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。 \ No newline at end of file
+Serial 框架当前支持 cdc acm, ftdi, cp210x, ch34x, pl2303,gsm 驱动。当前支持两种使用方式,
+一种是使用源生 CherryUSB usbhost serial API 进行操作,另一种是基于平台封装的 API 操作,比如 rt-thread device API。,nuttx posix API。
+
+下面演示的是使用 CherryUSB usbhost serial API 进行串口回环测试,并且使用阻塞发送,异步读取的方式:
+
+.. 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) {
+ /* for common, we use timeout with 0xffffffff, this is just a test */
+ 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;
+ usb_osal_msleep(10); // 11.52 Byte/ms at 115200bps --> 64Byte/5.5ms
+
+ 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);
+ 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;
+ }
+ }
+ USB_LOG_RAW("serial loopback test success\r\n");
+ 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);
+
+
+用户需要考虑以下三种场景:
+
+- USB2TTL 设备 + 启用了波特率,这种情况下需要使用 `usbh_serial_write` 和 `usbh_serial_read` 进行收发数据, **并且需要根据波特率控制发送频率,防止对端丢包**;
+
+- 纯 USB 设备 + 未启动波特率,这种情况下可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async` 进行异步收发数据,阻塞则用 `usbh_serial_write` 并且不需要控制发送频率。不可以使用 `usbh_serial_read`。
+
+- 纯 USB 设备 + 启动波特率,同 1,但是速率打折扣。不可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async`。如果是 GSM 设备需要使用第一种。 \ No newline at end of file