summaryrefslogtreecommitdiff
path: root/docs/source
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2024-11-27 19:49:31 +0800
committersakumisu <[email protected]>2024-11-27 20:17:05 +0800
commit015aa774879792d42d8d358a6814585f1f64303d (patch)
tree723136b51aa9cea9f7ce4d1429b643c7ca334263 /docs/source
parent4416dfa5cf35ff23dc7c7ef46a4b2b7d7c698109 (diff)
docs: update rst
Diffstat (limited to 'docs/source')
-rw-r--r--docs/source/demo/usbd_cdc_acm.rst102
-rw-r--r--docs/source/demo/usbd_hid.rst2
-rw-r--r--docs/source/demo/usbd_msc.rst37
-rw-r--r--docs/source/demo/usbd_video.rst81
-rw-r--r--docs/source/quick_start/demo.rst25
-rw-r--r--docs/source/usb/usb_ext.rst2
6 files changed, 248 insertions, 1 deletions
diff --git a/docs/source/demo/usbd_cdc_acm.rst b/docs/source/demo/usbd_cdc_acm.rst
index 8a6c4baf..be330b4c 100644
--- a/docs/source/demo/usbd_cdc_acm.rst
+++ b/docs/source/demo/usbd_cdc_acm.rst
@@ -1,2 +1,104 @@
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_hid.rst b/docs/source/demo/usbd_hid.rst
index c51e3627..68b6b285 100644
--- a/docs/source/demo/usbd_hid.rst
+++ b/docs/source/demo/usbd_hid.rst
@@ -1,2 +1,4 @@
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
index eb4dd164..2f8469fb 100644
--- a/docs/source/demo/usbd_msc.rst
+++ b/docs/source/demo/usbd_msc.rst
@@ -1,2 +1,39 @@
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_STACKSIZE` 会影响 U 盘的读写速度,必须是 block_size 的整数倍,当然,也会增加 RAM 的占用。
+
+- 如果 RAM 例程可以用,但是介质更换成 SD 或者 FLASH 后不可用,则一定是介质驱动问题。 \ No newline at end of file
diff --git a/docs/source/demo/usbd_video.rst b/docs/source/demo/usbd_video.rst
index 800ca358..a3e085d3 100644
--- a/docs/source/demo/usbd_video.rst
+++ b/docs/source/demo/usbd_video.rst
@@ -1,2 +1,83 @@
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` 传输数据
+
+1,传输采用双缓冲的形式, **MAX_PACKETS_IN_ONE_TRANSFER** 表示一次传输可以携带多少个 **MAX_PAYLOAD_SIZE**,通常 IP 只能为 1。
+
+2,在中断完成中,调用 `usbd_video_stream_split_transfer` 继续下一次传输,直到返回为 true 表示传输完成。这边的分裂传输只是表示将图片数据拆成 **MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE** 份传输。
+
+3,通常 IP 不支持一次传输非常大的数据,比如传输 1MB,因此需要做分裂传输,但是会增加中断次数。并且一次传输非常大数据也是需要足够的 RAM。
+
+.. 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[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
+
+ void video_test(uint8_t busid)
+ {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ while (1) {
+ if (tx_flag) {
+ iso_tx_busy = true;
+ usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
+ while (iso_tx_busy) {
+ if (tx_flag == 0) {
+ break;
+ }
+ }
+ }
+ }
+ } \ No newline at end of file
diff --git a/docs/source/quick_start/demo.rst b/docs/source/quick_start/demo.rst
index a108143f..7dd15d3f 100644
--- a/docs/source/quick_start/demo.rst
+++ b/docs/source/quick_start/demo.rst
@@ -33,9 +33,32 @@
仓库参考:https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
-- 飞腾派支持两个 USB3.0 主机, 两个 USB2.0 主从机
+- 飞腾派支持两个 USB3.0 主机(采用 XHCI), 两个 USB2.0 主从机
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
+基于 Essemi 系列芯片
+---------------------------
+
+仓库参考:https://github.com/CherryUSB/cherryusb_es32
+
+- 支持全速和高速主从机
+
+基于 NXP MCX系列芯片
+---------------------------
+
+仓库参考:https://github.com/CherryUSB/cherryusb_mcx 或者 https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx
+
+- 支持全速 IP 和高速 IP, 高速 IP 支持主机和从机
+
+- 支持全速和高速主从机
+
+基于 Artinchip 系列芯片
+---------------------------
+
+仓库参考:https://gitee.com/artinchip/luban-lite
+
+- 支持全速和高速主从机,主机采用 EHCI + OHCI。
+
基于 ST 系列芯片
---------------------------
diff --git a/docs/source/usb/usb_ext.rst b/docs/source/usb/usb_ext.rst
index b403f476..fa81f728 100644
--- a/docs/source/usb/usb_ext.rst
+++ b/docs/source/usb/usb_ext.rst
@@ -1,3 +1,5 @@
+.. _usb_ext:
+
USB 知识点拓展
===========================