diff options
| author | sakumisu <[email protected]> | 2026-01-30 22:10:34 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2026-01-30 23:16:00 +0800 |
| commit | eaefb8ed21ed23f732e8b608ed7948e6b71ab0d8 (patch) | |
| tree | 427acdc61cd9bbe9a03f500bfa604a425ed3b1e4 /docs/source/demo | |
| parent | 76b3720445f5b2396f3cd7dfdbecc277cafc76e7 (diff) | |
docs: update docs and add english version
Signed-off-by: sakumisu <[email protected]>
Diffstat (limited to 'docs/source/demo')
25 files changed, 0 insertions, 1007 deletions
diff --git a/docs/source/demo/img/cherryadb.png b/docs/source/demo/img/cherryadb.png Binary files differdeleted file mode 100644 index 512586b9..00000000 --- a/docs/source/demo/img/cherryadb.png +++ /dev/null diff --git a/docs/source/demo/img/otg.png b/docs/source/demo/img/otg.png Binary files differdeleted file mode 100644 index 9605176a..00000000 --- a/docs/source/demo/img/otg.png +++ /dev/null diff --git a/docs/source/demo/img/rtt_adb_shell1.png b/docs/source/demo/img/rtt_adb_shell1.png Binary files differdeleted file mode 100644 index df4964a2..00000000 --- a/docs/source/demo/img/rtt_adb_shell1.png +++ /dev/null diff --git a/docs/source/demo/img/rtt_adb_shell2.png b/docs/source/demo/img/rtt_adb_shell2.png Binary files differdeleted file mode 100644 index 88d99a6a..00000000 --- a/docs/source/demo/img/rtt_adb_shell2.png +++ /dev/null diff --git a/docs/source/demo/img/usbh_serial.png b/docs/source/demo/img/usbh_serial.png Binary files differdeleted file mode 100644 index da929c4a..00000000 --- a/docs/source/demo/img/usbh_serial.png +++ /dev/null diff --git a/docs/source/demo/usb_otg.rst b/docs/source/demo/usb_otg.rst deleted file mode 100644 index 78692cc0..00000000 --- a/docs/source/demo/usb_otg.rst +++ /dev/null @@ -1,15 +0,0 @@ -OTG 功能的使用 -========================= - -如果需要使用 OTG 功能,首先使用的芯片需要支持 ID 检测功能,然后使能 ``CONFIG_USB_OTG_ENABLE`` 宏,将之前的例程中 ``usbh_initialize`` 或者 ``usbh_initialize`` -替换成 ``usbotg_initialize`` 即可。 - -ID 检测电路根据不同的 USB 接口类型有所不同,常见的有 micro-USB 和 USB-C 两种接口类型。 - -- 如果是 micro-USB 接口,则将 ID 线连接到芯片的 ID 引脚,并使能 ID 功能即可。 -- 如果是 USB-C 接口,由于没有 ID 引脚,则需要借助 CC 电路转换成 ID 然后连接到芯片的 ID 引脚,常见电路图如下所示(DNP 表示不焊接): - -.. figure:: img/otg.png - - -.. note:: 除 ID 引脚以外,还需要增加 VBUS 输出开关控制,当工作在 host 时,开启 VBUS 供电,当工作在 device 时,关闭 VBUS 供电。
\ No newline at end of file diff --git a/docs/source/demo/usbd_adb.rst b/docs/source/demo/usbd_adb.rst deleted file mode 100644 index 92a3043e..00000000 --- a/docs/source/demo/usbd_adb.rst +++ /dev/null @@ -1,28 +0,0 @@ -usbd_adb -=============== - -本节主要介绍如何使用 adb device。支持 **cherrysh** 和 rt-thread **msh**,只需要在 main 中添加以下初始化即可。 - -.. code-block:: C - - cherryadb_init(0, xxxxx); - -如果使用 rt-thread,还需要在 menuconfig 中使能 adb device。 - -.. figure:: img/rtt_adb_shell1.png - -进入 adb --------------- - -- 使用 **cherrysh** 时枚举完成以后自动进入 adb 模式 -- 使用 **msh** 需要在 **msh** 中输入 ``adb_enter`` 进入 adb 模式 - -退出 adb --------------- - -- 使用 **cherrysh** 时输入 ``exit`` 退出 adb 模式 -- 使用 **msh** 需要在 **msh** 中输入 ``adb_exit`` 退出 adb 模式 - -.. figure:: img/cherryadb.png - -.. figure:: img/rtt_adb_shell2.png diff --git a/docs/source/demo/usbd_audiov1.rst b/docs/source/demo/usbd_audiov1.rst deleted file mode 100644 index 794ac8f6..00000000 --- a/docs/source/demo/usbd_audiov1.rst +++ /dev/null @@ -1,7 +0,0 @@ -usbd_audiov1 -=============== - -在使用 UAC1.0 时,需要注意以下几点: - -- 在使用windows 时,当修改描述符任意参数时,必须同步修改字符串描述符,并且卸载驱动,否则windows会认为设备未更改,继续使用旧的驱动,导致无法识别设备。Linux 不受此限制。 -- QQ 群文件中下载 RemoveGhostDev64.exe 可以自动删除所有 USB 注册的驱动信息,无需第一步
\ No newline at end of file diff --git a/docs/source/demo/usbd_audiov2.rst b/docs/source/demo/usbd_audiov2.rst deleted file mode 100644 index 0390f17d..00000000 --- a/docs/source/demo/usbd_audiov2.rst +++ /dev/null @@ -1,9 +0,0 @@ -usbd_audiov2 -=============== - -在使用 UAC2.0 时,需要注意以下几点: - -- 在使用windows 时,当修改描述符任意参数时,必须同步修改字符串描述符,并且卸载驱动,否则windows会认为设备未更改,继续使用旧的驱动,导致无法识别设备。Linux 不受此限制。 -- QQ 群文件中下载 RemoveGhostDev64.exe 可以自动删除所有 USB 注册的驱动信息,无需第一步 -- windows 10 uac2.0 功能不完善,请使用 windows 11 测试uac2.0 功能。Linux 不受此限制 -- windows 中设置的采样率表范围在多通道时(通道数大于2)计算有误,比如设置 8K~96K,那么实际是大于等于8K 小于96K,而非小于等于96K。Linux 不受此限制 diff --git a/docs/source/demo/usbd_cdc_acm.rst b/docs/source/demo/usbd_cdc_acm.rst deleted file mode 100644 index be330b4c..00000000 --- a/docs/source/demo/usbd_cdc_acm.rst +++ /dev/null @@ -1,104 +0,0 @@ -usbd_cdc_acm -=============== - -本 demo 主要用于演示 cdc acm 功能,包含收发测试,DTR 控制,ZLP 测试,性能测试。 - -- 开辟读写 buffer,用于收发数据,并且buffer需要用 nocache 修饰,这里我们读写都是用 2048字节,是为了后面的 ZLP 测试和性能测试使用。 - -.. code-block:: C - - USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/ - USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; - - -- 在协议栈事件回调中,我们需要在枚举完成后启动第一次传输,并清除相关 flag,可以在 reset 事件中清除,也可以在 configured 事件中清除。 - -.. code-block:: C - - static void usbd_event_handler(uint8_t busid, uint8_t event) - { - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - ep_tx_busy_flag = false; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048); - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } - } - -- 在接收完成中断中继续发起接收;在发送完成中断中判断是否需要发送 ZLP。 - -.. code-block:: C - - void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) - { - USB_LOG_RAW("actual out len:%d\r\n", nbytes); - // for (int i = 0; i < 100; i++) { - // printf("%02x ", read_buffer[i]); - // } - // printf("\r\n"); - /* setup next out ep read transfer */ - usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048); - } - - void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) - { - USB_LOG_RAW("actual in len:%d\r\n", nbytes); - - if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { - /* send zlp */ - usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0); - } else { - ep_tx_busy_flag = false; - } - } - -- 以下是为了测试 DTR 功能并控制 USB 发送,DTR 和 RTS 只用于搭配 UART 使用,如果是纯 USB,没什么用,这里仅做测试。DTR 开关使用任意串口上位机并勾选 DTR。 - -.. code-block:: C - - void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr) - { - if (dtr) { - dtr_enable = 1; - } else { - dtr_enable = 0; - } - } - -- 在主函数中一直调用发送即可 - -.. code-block:: C - - void cdc_acm_data_send_with_dtr_test(uint8_t busid) - { - if (dtr_enable) { - ep_tx_busy_flag = true; - usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048); - while (ep_tx_busy_flag) { - } - } - } - -- 上述我们需要注意,长度设置为 2048 是为了测试 ZLP 功能,通常实际使用时,接收长度应该使用 CDC_MAX_MPS 。具体原因参考 :ref:`usb_ext` -- 如果需要做性能测试,使用 tools/test_srcipts/test_cdc_speed.py 进行测试,并在测试之前删除 `usbd_cdc_acm_bulk_out` 和 `usbd_cdc_acm_bulk_in` 中的打印,否则会影响测试结果。 - - -此外,对于 CDC ACM 搭配 OS 的情况,通常我们 read 使用异步并将数据存储到 ringbuffer 中,write 使用同步搭配 sem 使用。
\ No newline at end of file diff --git a/docs/source/demo/usbd_ecm.rst b/docs/source/demo/usbd_ecm.rst deleted file mode 100644 index c4c64ab5..00000000 --- a/docs/source/demo/usbd_ecm.rst +++ /dev/null @@ -1,2 +0,0 @@ -usbd_cdc_ecm -=============== diff --git a/docs/source/demo/usbd_hid.rst b/docs/source/demo/usbd_hid.rst deleted file mode 100644 index 68b6b285..00000000 --- a/docs/source/demo/usbd_hid.rst +++ /dev/null @@ -1,4 +0,0 @@ -usbd_hid -=============== - -HID 功能比较简单,因此不作赘述,需要注意,使用 hid custom 例程时,需要搭配 `tools/test_srcipts/test_hid_inout.py` 使用。
\ No newline at end of file diff --git a/docs/source/demo/usbd_msc.rst b/docs/source/demo/usbd_msc.rst deleted file mode 100644 index ff59aada..00000000 --- a/docs/source/demo/usbd_msc.rst +++ /dev/null @@ -1,39 +0,0 @@ -usbd_msc -=============== - -本节主要演示 USB 模拟 U 盘功能。默认使用RAM 作为存储介质模拟 U 盘。 - -- 实现 U 盘的读写和获取容量接口,注意,容量 block_num 为虚拟的,实际没有这么多 block,读写的数据超过 BLOCK_COUNT 会丢弃。 - -block_size 一般为 512/2048/4096。 - -.. code-block:: C - - void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size) - { - *block_num = 1000; //Pretend having so many buffer,not has actually. - *block_size = BLOCK_SIZE; - } - int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) - { - if (sector < BLOCK_COUNT) - memcpy(buffer, mass_block[sector].BlockSpace, length); - return 0; - } - - int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) - { - if (sector < BLOCK_COUNT) - memcpy(mass_block[sector].BlockSpace, buffer, length); - return 0; - } - -- 默认上述 API 在中断中执行,如果需要在非中断中执行,可以选择如下: - -1,裸机下开启 `CONFIG_USBDEV_MSC_POLLING` 并在 while1 中调用 `usbd_msc_polling`,则读写函数在 while1 中执行。 - -2, OS 下开启 `CONFIG_USBDEV_MSC_THREAD`,则读写函数在线程中执行。 - -- 修改 `CONFIG_USBDEV_MSC_BUFSIZE` 会影响 U 盘的读写速度,必须是 block_size 的整数倍,当然,也会增加 RAM 的占用。 - -- 如果 RAM 例程可以用,但是介质更换成 SD 或者 FLASH 后不可用,则一定是介质驱动问题。
\ No newline at end of file diff --git a/docs/source/demo/usbd_rndis.rst b/docs/source/demo/usbd_rndis.rst deleted file mode 100644 index 40fba402..00000000 --- a/docs/source/demo/usbd_rndis.rst +++ /dev/null @@ -1,2 +0,0 @@ -usbd_rndis -=============== diff --git a/docs/source/demo/usbd_vendor.rst b/docs/source/demo/usbd_vendor.rst deleted file mode 100644 index b38631b1..00000000 --- a/docs/source/demo/usbd_vendor.rst +++ /dev/null @@ -1,44 +0,0 @@ -vendor device 驱动编写 -=========================== - -本节主要介绍如何编写一个 vendor device 驱动。 - -- 首先复制一份 class/template/usbd_xxx.c 文件 -- 实现以下三个回调函数,通常来说,vendor 驱动只需要实现 vendor_handler - -.. code-block:: C - - intf->class_interface_handler = xxx_class_interface_request_handler; - intf->class_endpoint_handler = NULL; - intf->vendor_handler = NULL; - intf->notify_handler = xxx_notify_handler; - -- 举例如下 - -case1 演示对于主机 IN 数据的处理,将数据拷贝到 *data 中,并指定*len 的长度。协议栈会自动发送给主机,不需要用户手动调用发送 API。 - -case2 演示对于主机 OUT 数据的处理,当执行到此函数时,说明数据都已经接收完成,可以直接读取 *data 中的数据,长度为 *len。 - -.. code-block:: C - - static int xxx_vendor_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) - { - USB_LOG_WRN("XXX Class request: " - "bRequest 0x%02x\r\n", - setup->bRequest); - - switch (setup->bRequest) { - case 1: - memcpy(*data, xxx, sizeof(xxx)); - *len = sizeof(xxx); - case 2: - hexdump(*data, *len); - default: - USB_LOG_WRN("Unhandled XXX Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - - return 0; - } - -- 最后使用形如 usbd_add_interface(busid, usbd_xxx_init_intf(&intf)) 注册接口
\ No newline at end of file diff --git a/docs/source/demo/usbd_video.rst b/docs/source/demo/usbd_video.rst deleted file mode 100644 index e215abde..00000000 --- a/docs/source/demo/usbd_video.rst +++ /dev/null @@ -1,83 +0,0 @@ -usbd_video -=============== - -本节主要演示 USB UAC 功能,支持 YUYV, MJPEG, H264 格式。为了方便演示,都采用的静态图。 - -demo 包含 **video_static_yuyv_template**, **video_static_mjpeg_template**, **video_static_h264_template**, 仅描述符和图片数据不同。 - -- 在高速模式下,默认最大是1024字节,但是如果芯片支持 additional transcations,可以配置为最高 2048字节或者3072字节,这样可以提高传输效率。 - -.. code-block:: C - - #ifdef CONFIG_USB_HS - #define MAX_PAYLOAD_SIZE 1024 // for high speed with one transcations every one micro frame - #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11)) - - // #define MAX_PAYLOAD_SIZE 2048 // for high speed with two transcations every one micro frame - // #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 2)) | (0x01 << 11)) - - // #define MAX_PAYLOAD_SIZE 3072 // for high speed with three transcations every one micro frame - // #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 3)) | (0x02 << 11)) - - #else - #define MAX_PAYLOAD_SIZE 1020 - #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11)) - #endif - -- 通常只需要修改 WIDTH 和 HEIGHT - -.. code-block:: C - - #define WIDTH (unsigned int)(640) - #define HEIGHT (unsigned int)(480) - - #define CAM_FPS (30) - #define INTERVAL (unsigned long)(10000000 / CAM_FPS) - #define MIN_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) //16 bit - #define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) - #define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2) - -- USB 端点配置,默认 interval 为 1,也就是全速模式下 1ms,高速模式下 125us。同步类型使用异步模式。 - -.. code-block:: C - - /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */ - USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01), - - -- 使用 `usbd_video_stream_start_write` 传输数据, 最后 **do_copy** 选项表示是否将数据 copy 到 packet_buffer, -如果不选择 copy, 则会直接在原图像数据中填充头部信息,并直接发送,达到 zero copy 功能。 - -- 因为提供的是静态数据,不能被修改,因此需要重新给一个 frame_buffer 用于图像传输,在实际对接 camera 场景中是动态数据,直接使用 camera 的数据缓冲区即可。 - - -.. code-block:: C - - void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) - { - if (usbd_video_stream_split_transfer(busid, ep)) { - /* one frame has done */ - iso_tx_busy = false; - } - } - - USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE]; - USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[32 * 1024]; - - void video_test(uint8_t busid) - { - memset(packet_buffer, 0, sizeof(packet_buffer)); - - while (1) { - if (tx_flag) { - iso_tx_busy = true; - memcpy(frame_buffer, cherryusb_mjpeg, sizeof(cherryusb_mjpeg)); // cherryusb_mjpeg is a static MJPEG frame buffer, so we need copy it to frame_buffer - usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)frame_buffer, sizeof(cherryusb_mjpeg), false); - while (iso_tx_busy) { - if (tx_flag == 0) { - break; - } - } - } - } - }
\ No newline at end of file diff --git a/docs/source/demo/usbd_webusb.rst b/docs/source/demo/usbd_webusb.rst deleted file mode 100644 index 0df9bef6..00000000 --- a/docs/source/demo/usbd_webusb.rst +++ /dev/null @@ -1,21 +0,0 @@ -usbd_webusb -=============== - -本 demo 主要演示 webusb 功能,webusb 主要用于弹出网页并对 USB 设备进行访问。示例使用 webusb_hid_template.c。 - -- 在注册描述符时注册 BOS, MSOSV2, WEBUSB 描述符即可。 - -.. code-block:: C - - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); - usbd_webusb_desc_register(busid, &webusb_url_desc); - -- 增加一个接口描述符用于 webusb - -.. code-block:: C - - USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00) - -- 其余使用 hid 描述符,不再赘述 -- 枚举完成后,电脑右下角会弹出网页信息,点击即可打开网页
\ No newline at end of file diff --git a/docs/source/demo/usbd_winusb.rst b/docs/source/demo/usbd_winusb.rst deleted file mode 100644 index 0a6d4de9..00000000 --- a/docs/source/demo/usbd_winusb.rst +++ /dev/null @@ -1,55 +0,0 @@ -usbd_winusb -=============== - -本节主要介绍 winusb 驱动。winusb 是 windows 为了让用户友好的访问 USB 自定义类设备提供的一套通用驱动,其实本质就是 CDC ACM,只不过没有设置波特率的命令。 -WINUSB 版本根据 USB 版本分为 V1/V2 版本,V2 版本需要包含 BOS 描述符,V1 版本不需要。 **V2 版本需要在设备描述符中设置为 USB2.1 的版本号**。 - -.. note:: 更换 winusb 描述符任意配置可能会枚举成功但是无法识别设备,需要删除 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags 下所有注册表项,重新插拔设备后生效。 - -- V1 版本注册描述符 - -.. code-block:: C - - const struct usb_descriptor winusbv1_descriptor = { - .device_descriptor_callback = device_descriptor_callback, - .config_descriptor_callback = config_descriptor_callback, - .device_quality_descriptor_callback = device_quality_descriptor_callback, - .string_descriptor_callback = string_descriptor_callback, - .msosv1_descriptor = &msosv1_desc - }; - - OR - - usbd_msosv1_desc_register(busid, &msosv1_desc); - -- V2 版本注册描述符 - -.. code-block:: C - - const struct usb_descriptor winusbv2_descriptor = { - .device_descriptor_callback = device_descriptor_callback, - .config_descriptor_callback = config_descriptor_callback, - .device_quality_descriptor_callback = device_quality_descriptor_callback, - .string_descriptor_callback = string_descriptor_callback, - .msosv2_descriptor = &msosv2_desc, - .bos_descriptor = &bos_desc, - }; - - OR - - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); - - -- 接口描述符注册 - -.. code-block:: C - - /* Interface 0 */ - USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02), - /* Endpoint OUT 2 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - /* Endpoint IN 1 */ - USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00), - -- 读写操作与 CDC ACM 相同,不再赘述
\ No newline at end of file diff --git a/docs/source/demo/usbh_bluetooth.rst b/docs/source/demo/usbh_bluetooth.rst deleted file mode 100644 index a93844ea..00000000 --- a/docs/source/demo/usbh_bluetooth.rst +++ /dev/null @@ -1,2 +0,0 @@ -usbh_bluetooth -=============== diff --git a/docs/source/demo/usbh_hid.rst b/docs/source/demo/usbh_hid.rst deleted file mode 100644 index 6d519319..00000000 --- a/docs/source/demo/usbh_hid.rst +++ /dev/null @@ -1,55 +0,0 @@ -usbh_hid -=============== - -本节主要介绍 HID 类的使用。 - -- HID 枚举完成回调中创建一次性线程 - -.. code-block:: C - - - void usbh_hid_run(struct usbh_hid *hid_class) - { - usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class); - } - - void usbh_hid_stop(struct usbh_hid *hid_class) - { - } - - -- 这里我们使用 usbh_submit_urb 的异步操作,在中断中处理数据并继续接收下一次数据。 - -.. code-block:: C - - static void usbh_hid_thread(void *argument) - { - int ret; - struct usbh_hid *hid_class = (struct usbh_hid *)argument; - ; - - /* test with only one buffer, if you have more hid class, modify by yourself */ - - /* Suggest you to use timer for int transfer and use ep interval */ - usbh_int_urb_fill(&hid_class->intin_urb, hid_class->hport, hid_class->intin, hid_buffer, hid_class->intin->wMaxPacketSize, 0, usbh_hid_callback, hid_class); - ret = usbh_submit_urb(&hid_class->intin_urb); - if (ret < 0) { - goto delete; - } - // clang-format off - delete: - usb_osal_thread_delete(NULL); - // clang-format on - } - -- 当然,也可以不使用异步操作,而是使用 timeout 的同步操作。 -- HID 使用的是中断传输,因此正常来说,我们需要根据 **bInterval** 来设置定时器,定时触发中断传输,demo 这里没有使用,如果对时间有精确要求,可以选择使用定时器来触发异步发送。 -- 以 hub 通信为例,采用的是一次性定时器,也可以使用周期性定时器。 - -.. code-block:: C - - hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed) / 1000, hub_int_timeout, hub, 0); - -.. note:: - - 这里的 `USBH_GET_URB_INTERVAL` 是一个宏定义,用于根据 binterval 计算 URB 的传输间隔时间, 单位是 us,而定时器最低是 ms ,因此需要除以 1000。对于小于等于 1ms 的不需要使用定时器。
\ No newline at end of file diff --git a/docs/source/demo/usbh_msc.rst b/docs/source/demo/usbh_msc.rst deleted file mode 100644 index 83956cc2..00000000 --- a/docs/source/demo/usbh_msc.rst +++ /dev/null @@ -1,56 +0,0 @@ -usbh_msc -=============== - -本节主要介绍主机 MSC 使用。借助 FATFS 实现读写功能。 - -- 在 msc 枚举完成的回调中注册一个线程,用于读写操作。 - -.. code-block:: C - - void usbh_msc_run(struct usbh_msc *msc_class) - { - usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class); - } - - void usbh_msc_stop(struct usbh_msc *msc_class) - { - } - - -- 不使用 fatfs,则直接使用 usbh_msc_scsi_read10 或者 usbh_msc_scsi_write10 函数进行读写操作。 -- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/fatfs/usbh_fatfs.c` - -.. code-block:: C - - static void usbh_msc_thread(void *argument) - { - int ret; - struct usbh_msc *msc_class = (struct usbh_msc *)argument; - - /* test with only one buffer, if you have more msc class, modify by yourself */ - #if 1 - /* get the partition table */ - ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1); - if (ret < 0) { - USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret); - goto delete; - } - for (uint32_t i = 0; i < 512; i++) { - if (i % 16 == 0) { - USB_LOG_RAW("\r\n"); - } - USB_LOG_RAW("%02x ", partition_table[i]); - } - USB_LOG_RAW("\r\n"); - #endif - - #if TEST_USBH_MSC_FATFS - usb_msc_fatfs_test(); - #endif - // clang-format off - delete: - usb_osal_thread_delete(NULL); - // clang-format on - } - -- 最后处理完成或者失败后,删除线程。
\ No newline at end of file diff --git a/docs/source/demo/usbh_net.rst b/docs/source/demo/usbh_net.rst deleted file mode 100644 index 8757991e..00000000 --- a/docs/source/demo/usbh_net.rst +++ /dev/null @@ -1,156 +0,0 @@ -usbh_net -=============== - -本节主要介绍 USB 网卡的使用,当前已经支持和测试以下 USB 网卡: - -- 4G 网卡:EC20(ECM/RNDIS)、手机(RNDIS)、SIMCOM7600(RNDIS)、ML307R(RNDIS)、AIR780(RNDIS) - -.. caution:: 请注意,部分 4G 网卡默认不带自动拨号功能,请更换固件或者使用 AT 配置成自动拨号,否则无法获取 IP。 - -- USB 以太网卡:ASIX AX88772,REALTEK RTL8152 -- USB WIFI 网卡: 博流 BL616(RNDIS/ECM) - -USB 网卡相关的宏和文件 ------------------------- - -网卡相关的宏如下,主要用于根据不同的网络组件注册网卡驱动: - -.. code-block:: C - - // #define CONFIG_USBHOST_PLATFORM_CDC_ECM - // #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS - // #define CONFIG_USBHOST_PLATFORM_CDC_NCM - // #define CONFIG_USBHOST_PLATFORM_ASIX - // #define CONFIG_USBHOST_PLATFORM_RTL8152 - -.. note:: 如果使用了 Kconfig 系统,上述宏自定生成,其他平台请手动定义。 - -USB 网卡传输层面已经对接好了相关网络组件,列举如下: - -- 自定义 OS + LWIP 请使用 **platform/lwip/usbh_lwip.c**,需要自行包含该文件,并使能上述相关的宏。并在初始化 USB 之前调用 `tcpip_init(NULL, NULL)` -- RT-THREAD + LWIP 请使用 **platform/rtthread/usbh_lwip.c**,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,勾选 rt-thread lwip以后自动调用 `tcpip_init(NULL, NULL)` -- ESP-IDF + LWIP 请使用 **platform/freertos/usbh_net.c**,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,并且在初始化 USB 之前调用 `esp_netif_init()` + `esp_event_loop_create_default()` -- NUTTX + NUTTX 网络组件 请使用 **platform/nuttx/usbh_net.c**,在 Kconfig 中使能对应的网卡驱动后自动勾选该文件,勾选网络组件以后自动调用 - -.. note:: 如果是自行添加代码,别忘了添加 USB 网卡驱动相关的源文件,例如 **class/usbh_cdc_ecm.c**。所以我们推荐搭配对应平台使用哦,省去自己添加文件的麻烦 - -USB 网卡对接过程 -------------------- - -下面举例对接 LWIP 的对接过程。 - -- 在 USB 网卡枚举完成以后,会 **自动** 调用 `usbh_xxx_run` 函数,此时注册 netif 驱动,并且开启 DHCP 客户端和获取 IP 的定时器。 - -.. code-block:: C - - void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) - { - struct netif *netif = &g_cdc_ecm_netif; - - netif->hwaddr_len = 6; - memcpy(netif->hwaddr, cdc_ecm_class->mac, 6); - - IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); - IP4_ADDR(&g_netmask, 0, 0, 0, 0); - IP4_ADDR(&g_gateway, 0, 0, 0, 0); - - netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ecm_if_init, tcpip_input); - netif_set_default(netif); - while (!netif_is_up(netif)) { - } - - dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true); - if (dhcp_handle == NULL) { - USB_LOG_ERR("timer creation failed! \r\n"); - while (1) { - } - } - - usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL); - #if LWIP_DHCP - dhcp_start(netif); - usb_osal_timer_start(dhcp_handle); - #endif - } - -- `usbh_lwip_eth_output_common` 用于将发送 pbuf 组装成 USB 网卡数据包 -- `usbh_lwip_eth_input_common` 用于将 USB 网卡数据组装成 pbuf -- 实际网卡发送和接收处理 - -.. code-block:: C - - static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p) - { - int ret; - (void)netif; - - usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf()); - ret = usbh_cdc_ecm_eth_output(p->tot_len); - if (ret < 0) { - return ERR_BUF; - } else { - return ERR_OK; - } - } - - void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen) - { - usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen); - } - -- USB 网卡 拔出以后会 **自动** 调用 `usbh_xxx_stop` 函数,此时需要停止 DHCP 客户端,删除定时器,并且移除 netif。 - -.. code-block:: C - - void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) - { - struct netif *netif = &g_cdc_ecm_netif; - (void)cdc_ecm_class; - - #if LWIP_DHCP - dhcp_stop(netif); - dhcp_cleanup(netif); - usb_osal_timer_delete(dhcp_handle); - #endif - netif_set_down(netif); - netif_remove(netif); - } - -- 因为 USB 网卡内部已经对接了LWIP,因此用户可以直接使用 LWIP 的 API,无需关心 USB 的实现。 - -USB 网卡 LWIP 配置宏相关注意事项 ------------------------------------- - -**LWIP_TCPIP_CORE_LOCKING_INPUT** 用于不使用 lwip 内置的 tcpip 线程,而使用 USB 自己的接收处理线程。 - -**LWIP_TCPIP_CORE_LOCKING** 在现在 lwip 版本中默认是打开的,也推荐必须打开。 - -**PBUF_POOL_BUFSIZE** 推荐大于1600,搭配 LWIP_TCPIP_CORE_LOCKING_INPUT 使用,因为我们提供了使用 zero mempy 的方式,使用静态 pbuf,而不是把数据 copy 到 pbuf 中。 - -**TCPIP_THREAD_STACKSIZE** 推荐大于 1K,防止栈溢出。 - -.. code-block:: C - - #if LWIP_TCPIP_CORE_LOCKING_INPUT != 1 - #warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread - #endif - - #if LWIP_TCPIP_CORE_LOCKING != 1 - #error must set LWIP_TCPIP_CORE_LOCKING to 1 - #endif - - #if PBUF_POOL_BUFSIZE < 1600 - #error PBUF_POOL_BUFSIZE must be larger than 1600 - #endif - - #if TCPIP_THREAD_STACKSIZE < 1024 - #error TCPIP_THREAD_STACKSIZE must be >= 1024 - #endif - - -总结 --------------- - -.. note:: 通过以上内容,我们可以看到 CherryUSB 对 USB 网卡的支持是非常完善的,用户只需要使能对应的宏或者勾选,就可以实现 USB 网卡的自动识别和驱动注册,无需手动初始化网卡相关配置,用户只需关注应用层,极大地方便了用户的使用。 - -具体移植文章可以参考开发者的一些笔记 https://club.rt-thread.org/ask/article/5cf3e9e0b2d95800.html
\ No newline at end of file diff --git a/docs/source/demo/usbh_serial.rst b/docs/source/demo/usbh_serial.rst deleted file mode 100644 index 619545c6..00000000 --- a/docs/source/demo/usbh_serial.rst +++ /dev/null @@ -1,196 +0,0 @@ -usbh_serial -=============== - -Serial 框架当前支持 cdc acm, ftdi, cp210x, ch34x, pl2303,gsm 驱动。 - -.. figure:: img/usbh_serial.png - -当前支持两种使用方式,一种是使用源生 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) { - 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:: 需要注意,例程中使用的是比较简单的先发送后读取的方式,因此发送的总长度不可以超过 CONFIG_USBHOST_SERIAL_RX_SIZE,正常使用 TX/RX 请分开进行。 - -用户需要考虑以下三种场景: - -- USB2TTL 设备 + 启用了波特率(USB2TTL设备必须启用波特率),这种情况下需要使用 `usbh_serial_write` 和 `usbh_serial_read` 进行收发数据, **并且 read 操作需要及时,防止 ringbuf 数据溢出而丢包**。不可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async` - -- 纯 USB 设备 + 未启动波特率,这种情况下可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async` 进行异步收发数据。阻塞则可以用 `usbh_serial_write` ,不可以使用 `usbh_serial_read`。 - -- 纯 USB 设备 + 启动波特率,同 1,但是接收速率会打折扣(因为多了一层 ringbuf)。此时也不可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async`。 **如果是 GSM 设备请使用第一种场景**。 - -.. note:: 简单来说就是,如果接收数据需要用到ringbuf转一层的,请使用第一种场景。 - -.. 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 - diff --git a/docs/source/demo/usbh_vendor.rst b/docs/source/demo/usbh_vendor.rst deleted file mode 100644 index b86bda60..00000000 --- a/docs/source/demo/usbh_vendor.rst +++ /dev/null @@ -1,127 +0,0 @@ -vendor host 驱动编写 -=========================== - -本节主要介绍如何编写一个 vendor host 驱动。 - -- 首先复制一份 class/template/usbh_xxx.c 文件 - -- 定义 class 驱动并使用 CLASS_INFO_DEFINE 前缀,这样,枚举完成后,协议栈自动通过 usbd_class_find_driver 来查找对应的驱动。 - -.. code-block:: C - - static const struct usbh_class_driver xxx_class_driver = { - .driver_name = "xxx", - .connect = usbh_xxx_connect, - .disconnect = usbh_xxx_disconnect - }; - - CLASS_INFO_DEFINE const struct usbh_class_info xxx_class_info = { - .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = 0, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .id_table = NULL, - .class_driver = &xxx_class_driver - }; - - -- 实现 connect 和 disconnect 函数, 在 connect 函数中,需要分配一个 xxx_class 结构体,在 disconnect 函数中释放 urb 和 xxx_class。 - -.. code-block:: C - - struct usbh_xxx { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *xxxin; - struct usb_endpoint_descriptor *xxxout; - struct usbh_urb xxxin_urb; - struct usbh_urb xxxout_urb; - - uint8_t intf; /* interface number */ - uint8_t minor; - - void *user_data; - }; - - static int usbh_xxx_connect(struct usbh_hubport *hport, uint8_t intf) - { - struct usb_endpoint_descriptor *ep_desc; - int ret; - - struct usbh_xxx *xxx_class = usbh_xxx_class_alloc(); - if (xxx_class == NULL) { - USB_LOG_ERR("Fail to alloc xxx_class\r\n"); - return -USB_ERR_NOMEM; - } - - return ret; - } - - - static int usbh_xxx_disconnect(struct usbh_hubport *hport, uint8_t intf) - { - int ret = 0; - - struct usbh_xxx *xxx_class = (struct usbh_xxx *)hport->config.intf[intf].priv; - - if (xxx_class) { - if (xxx_class->xxxin) { - usbh_kill_urb(&xxx_class->xxxin_urb); - } - - if (xxx_class->xxxout) { - usbh_kill_urb(&xxx_class->xxxout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - USB_LOG_INFO("Unregister xxx Class:%s\r\n", hport->config.intf[intf].devname); - usbh_xxx_stop(xxx_class); - } - - usbh_xxx_class_free(xxx_class); - } - - return ret; - } - -- 初始化端点 - -.. code-block:: C - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(xxx_class->intin, ep_desc); - } else { - USBH_EP_INIT(xxx_class->intout, ep_desc); - } - } - -- 最后设计收发 API,根据实际情况设计成同步 or 异步。 - -.. code-block:: C - - int usbh_xxx_in_transfer(struct usbh_xxx *xxx_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) - { - int ret; - struct usbh_urb *urb = &xxx_class->xxxin_urb; - - usbh_xxx_urb_fill(urb, xxx_class->hport, xxx_class->xxxin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; - } - - int usbh_xxx_out_transfer(struct usbh_xxx *xxx_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) - { - int ret; - struct usbh_urb *urb = &xxx_class->xxxout_urb; - - usbh_xxx_urb_fill(urb, xxx_class->hport, xxx_class->xxxout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; - }
\ No newline at end of file diff --git a/docs/source/demo/usbh_wifi.rst b/docs/source/demo/usbh_wifi.rst deleted file mode 100644 index be148c7d..00000000 --- a/docs/source/demo/usbh_wifi.rst +++ /dev/null @@ -1,2 +0,0 @@ -usbh_wifi -=============== |
