docs: update doc

This commit is contained in:
sakumisu
2024-08-21 20:04:18 +08:00
parent f0fc75179e
commit 43dc854b4d
11 changed files with 83 additions and 182 deletions

View File

@@ -1,43 +0,0 @@
USB 双通道麦克风和扬声器
============================
软件实现
------------
详细代码参考 `demo/audio_v1_mic_speaker_multichan_template.c`
.. code-block:: C
usbd_desc_register(audio_descriptor);
usbd_add_interface(usbd_audio_alloc_intf());
usbd_add_interface(usbd_audio_alloc_intf());
usbd_add_interface(usbd_audio_alloc_intf());
usbd_add_endpoint(&audio_in_ep);
usbd_add_endpoint(&audio_out_ep);
usbd_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT);
usbd_audio_add_entity(0x05, AUDIO_CONTROL_FEATURE_UNIT);
usbd_initialize();
- 调用 `audio_init` 配置 audio 描述符并初始化 usb 硬件
- 因为 麦克风+扬声器+控制需要 3 个接口,所以我们需要调用 `usbd_add_interface` 3 次
- 默认描述符中开启了 mute 和 volume 的控制,所以需要注册对应的 entity使用 `usbd_audio_add_entity`
.. code-block:: C
void usbd_audio_open(uint8_t intf)
{
}
void usbd_audio_close(uint8_t intf)
{
}
- 当我们打开 PC 的音量图标,或者音乐播放器、麦克风界面时,会调用到这两个接口,用于启动或者停止数据传输
.. code-block:: C
usbd_ep_start_write(AUDIO_IN_EP, write_buffer, 2048);
- 由于 audio 协议中没有应用层相关的协议,传输的只有音频的原始数据,所以直接调用 `usbd_ep_start_write` 即可,发送完成会进入完成中断
- 由于扬声器需要使用 out 端点,所以需要在 `usbd_configure_done_callback` 中启动第一次接收,当然如果没有能力接收,可以不启动,在想启动的时候启动

View File

@@ -1,78 +0,0 @@
USB 虚拟串口(无 UART 功能)
============================
USB 虚拟串口主要是借助 USB CDC ACM 类实现,将其模拟成一个 VCP 设备,当插在电脑上的时候,可以显示成一个串口设备。跟市面上的 USB2TTL模块的区别在于虚拟串口仅仅只使用到了 USB ,没有与串口UART外设进行连动。
软件实现
------------
详细代码参考 `demo/cdc_acm_template.c`
.. code-block:: C
usbd_desc_register(cdc_descriptor);
usbd_add_interface(usbd_cdc_acm_alloc_intf());
usbd_add_interface(usbd_cdc_acm_alloc_intf());
usbd_add_endpoint(&cdc_out_ep);
usbd_add_endpoint(&cdc_in_ep);
usbd_initialize();
- 调用 `cdc_acm_init` 配置 cdc acm 描述符并初始化 usb 硬件
- 因为 cdc 有 2 个接口,所以我们需要调用 `usbd_add_interface` 2 次
.. code-block:: C
void usbd_configure_done_callback(void)
{
/* setup first out ep read transfer */
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
}
void usbd_cdc_acm_bulk_out(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(CDC_OUT_EP, read_buffer, 2048);
}
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
/* send zlp */
usbd_ep_start_write(CDC_IN_EP, NULL, 0);
} else {
ep_tx_busy_flag = false;
}
}
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
{
if (dtr) {
dtr_enable = 1;
} else {
dtr_enable = 0;
}
}
void cdc_acm_data_send_with_dtr_test(void)
{
if (dtr_enable) {
memset(&write_buffer[10], 'a', 2038);
ep_tx_busy_flag = true;
usbd_ep_start_write(CDC_IN_EP, write_buffer, 2048);
while (ep_tx_busy_flag) {
}
}
}
- `usbd_cdc_acm_set_dtr` 函数是主机发送流控命令时的回调函数,这里我们使用 dtr ,当开启 dtr 时,启动发送
- `usbd_configure_done_callback` 是枚举完成的回调函数,因为 cdc acm 有 out 端点,所以我们需要在这里启动第一次数据的接收,当然,如果你现在没有能力接收数据,可以不启动。 **数据长度需要是最大包长的整数倍**
- `usbd_cdc_acm_bulk_out` 是接收完成中断回调,我们在这里面启动下一次接收
- `usbd_cdc_acm_bulk_in` 是发送完成中断回调,我们在这里检查发送长度是否是最大包长的整数,如果是,需要发送 zlp 包表示结束
- 调用 `usbd_ep_start_write` 进行发送需要注意如果返回值小于0不能执行下面的 while

View File

@@ -0,0 +1 @@
TODO

View File

@@ -1,42 +0,0 @@
USB 模拟 U 盘
============================
软件实现
------------
详细代码参考 `demo/msc_ram_template.c`
.. code-block:: C
usbd_desc_register(msc_ram_descriptor);
usbd_add_interface(usbd_msc_alloc_intf(MSC_OUT_EP, MSC_IN_EP));
usbd_initialize();
- 调用 `msc_ram_init` 配置 msc 描述符并初始化 usb 硬件
- 因为 msc 有1个接口所以我们需要调用 `usbd_add_interface` 1次
- msc 中的端点的数据流是协议栈这边管理,所以不需要用户注册端点的回调函数。同理 `usbd_configure_done_callback` 也不需要,为空即可
.. code-block:: C
void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
*block_num = 1000; //Pretend having so many buffer,not has actually.
*block_size = BLOCK_SIZE;
}
int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
{
return 0;
}
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
{
return 0;
}
- 实现三个接口即可使用 msc读写操作如果没有 os 则是在中断中
- `CONFIG_USBDEV_MSC_MAX_BUFSIZE` 可以为 512 的整数倍,更改此项,可以增加 msc 的读写速度,当然,也会消耗更多的 ram
.. note:: MSC 一般配合 rtos 使用,因为读写操作是阻塞的,放中断是不合适的, `CONFIG_USBDEV_MSC_THREAD` 则是使能 os 管理

View File

@@ -1,2 +0,0 @@
USB 摄像头
============================

View File

@@ -68,6 +68,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
usb/usb_desc
usb/usb_request
usb/usb_enum
usb/usb_ext
.. toctree::
:maxdepth: 1
@@ -93,10 +94,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
:maxdepth: 1
:caption: 基本例程
demo/cdc_acm
demo/msc_ram
demo/audio_mic_speaker
demo/usb_video
demo/index
.. toctree::
:maxdepth: 1

View File

@@ -17,9 +17,25 @@
仓库参考https://github.com/CherryUSB/cherryusb_hpmicro
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY支持主从机
- HPM 系列芯片均 USB 2.0 并且内置高速 PHY支持主从机,端点共 8/16 个,并且可以同时使用双向,不同芯片个数有差异
- USB 的相关应用位于 `samples/cherryusb` ,根据官方环境搭建完成后,即可编译使用。
基于 esp32s2/s3/p4 系列芯片
---------------------------
仓库参考https://github.com/CherryUSB/cherryusb_esp32
- esp32s2/s3 支持全速主从机esp32p4 支持高速主从机
- 默认提供主机 demo并且使用 esp 组件库进行开发, 在 https://components.espressif.com/ 中搜索 cherryusb 即可
基于飞腾派系列芯片
---------------------------
仓库参考https://gitee.com/phytium_embedded/phytium-free-rtos-sdk
- 飞腾派支持两个 USB3.0 主机, 两个 USB2.0 主从机
- USB 的相关应用位于 `example/peripheral/usb` ,根据官方环境搭建完成后,即可编译使用。
基于 ST 系列芯片
---------------------------
@@ -31,7 +47,7 @@
- F429 主从使用 USB1, 引脚 pb14/pb15, 并且都使用 dma 模式
- H7 设备使用 USB0, 引脚 pa11/pa12主机使用 USB_OTG_HS ,引脚 pb14/pb15并且需要做 nocache 处理
默认删除 Drivers ,所以需要使用 stm32cubemx 生成一下 Drivers 目录下的文件,demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
demo 底下提供了 **stm32xxx.ioc** 文件,双击打开,点击 **Generate Code** 即可。
.. caution:: 生成完以后,请使用 git reset 功能将被覆盖的 `main.c``stm32xxx_it.c` 文件撤回,禁止被 cubemx 覆盖。

View File

@@ -0,0 +1,24 @@
USB 知识点拓展
===========================
什么是分包
-------------
由于 USB 协议中规定了每个包的最大长度,所以当我们发送的数据长度超过了最大包长度时,就需要分包发送,这就是分包。比如 ep mps 为 64数据长度为 129则 USB 会按照 64 + 64 + 1 的形式传输。
而对于 USB IP 来说,分包分为软件分包和硬件分包,软件分包就是用户代码自行分包,这种 ip 一般都使用 FIFO 来进行,因为 FIFO 深度是有限的;第二种
则是使用硬件分包,这种 USB IP 一般带 DMA 或者描述符 DMA 功能,那么这种 IP 的效率无疑是最高的cherryusb 中充分利用了这点,使得 USB 速度能够达到最高。
对于软件分包来说,一次发送的长度即使是 16K **内部也是通过软件分包的,在这种情况下,发送长度的多少不会对速度有任何提升**
对于硬件分包来说,发送的长度会影响速度,因为硬件分包是通过 DMA 来进行的, **一次发送的长度越大DMA 的效率就越高,速度也就越快**。(当然,其他协议栈虽然使用了 dma但是部分代码实现还是按照一个包进行等于没用这也是速度低的一个原因
什么是 ZLP
-------------
ZLP顾名思义零长度数据包是 USB 设备在数据传输结束时,如果数据长度正好是最大包长度的整数倍,那么就会发送一个 ZLP 数据包,用来告诉主机数据传输结束。
当我们发送或者接收的时候,如果没有相关的协议告诉我们接收或者发送的长度,这种情况下我们就需要 ZLP 功能。
.. caution:: ZLP 功能仅限于 CONTROL 和 BULK 传输
比如 cdc acm本身是没有协议的所以我们发送需要 ZLP接收也需要 ZLP但是又由于 PC 的 USB 主机驱动默认 **接收不开 ZLP**, 因此,我们 **接收的长度必须设置为 EP MPS**,通常为 64 或者 512
而如果接收的数据不设置成 EP MPS ,就会带来数据接收不完成的问题,比如设置成 2048,如果主机发送的是 512/1025/1536则 USB IP 不会进入完成状态,因为完成的条件是数据等于 2048 或者最后一个包是短包。
再比如 MSC MSC 的逻辑是 CMD + DATA + STATUS 的流程CMD 阶段包含了要接收或者发送的数据长度,所以不需要 ZLP 功能。

View File

@@ -6,8 +6,8 @@
<= v0.10.2 初代版本
----------------------
- **用于定基本的框架,仅支持单 USB IP**
- **host 驱动每个 ep占用一个 硬件 pipe不支持动态使用硬件 pipe**
- **用于定基本的主从机框架,仅支持单 USB IP**
- **host 驱动每个 ep 占用一个 硬件 pipe不支持动态使用硬件 pipe**
- 相关 porting 需要使用此版本,后续不再支持(比如 ch32rp2040以及旧版本pusb2 和 xhci新版本不再提供源码
v1.0.0 过度版本
@@ -36,9 +36,8 @@ v1.3.0
- device 支持多种速度描述符自动选择功能(开启 CONFIG_USBDEV_ADVANCE_DESC
- device core 代码统一 ep0 buffer 的使用,用于美化代码
- host 增加 pl2303 驱动,使用 id table 来支持多个 vidpid增加 user_data 给用户使用
- host 网络 class 驱动增加 tx、rx buffer的宏增加 LWIP_TCPIP_CORE_LOCKING_INPUT 的使用,以便实现数据的零拷贝
- host hid 增加report api
- host 增加 pl2303 驱动;采用 id table 来支持多个 vidpid增加 user_data 给用户使用
- host 网络 class 驱动增加 tx、rx buffer 的宏,增加 LWIP_TCPIP_CORE_LOCKING_INPUT 的使用,以便实现数据的零拷贝
- porting 导入 bouffaloaicstm32f723 device驱动
- porting 中主机部分 urb->timeout 清0 的处理有点问题(大数据量传输时会出现 no pipe alloc 异常,主要原因是刚启动传输就完成了,还没判断 timeout就被修改为0了没有进入 take sem 流程),此版本已修复
- ehci enable iaad in usbh_kill_urbread ehci hcor offset from hccr caplengthenable ohci for ehci
@@ -50,7 +49,17 @@ v1.3.1
- bugfixaudiovideocdc ecm 相关宏结构体api
- host hub 枚举线程删除,使用 psc 线程,枚举方式更改为队列模式,取消同时枚举多个设备的功能
- host 扫描驱动信息和 instance 采用递归模式,删除链表扫描
- host 网络 class 驱动优化,支持接收 16K 以上的数据cdc ecm 不支持)
- 增加高级 memcpy api
- device 枚举相关删除打印(中断中不再做打印)
- porting 中 musb fifo配置修改为从 fifo table 获取(此代码参考 linux适配 es32sunxibeken
- host 网络 class 驱动优化,支持接收 16K 以上的数据cdc ecm 不支持),采用高级 memcpy api
- device 协议栈中打印删除(中断中不再做打印)
- porting 中 musb fifo配置修改为从 fifo table 获取(此代码参考 linux适配 es32sunxibeken
v1.4.0
----------------------
- device 开始支持 remote wakeup 功能, hid request(0x21),完善 GET STATUS 请求(可以通过 USB3CV 测试)
- device 增加 UF2, ADB, WEBUSB 功能, usbd_cdc 改名为 usbd_cdc_acm
- device msc 增加裸机的读写 polling 功能,将读写放在 while1中执行
- host 增加 usbwifi(bl616), xbox驱动重构 USB3.0 枚举逻辑
- host 中 cdc_acm,hid,msc,serial 传输共享 buffer如果存在多个相同的设备会有问题修改为单独的 buffer
- porting 重构 XHCI/PUSB2 驱动不开源ehci 和 ohci 文件改名;增加 remote wakeup api
- esp 组件库支持