基于现有 demo 快速验证

在学习 USB 或者是学习 CherryUSB 代码之前,我们需要先基于现有的 demo 进行快速验证,为什么?是为了提升对 USB 的兴趣,能有信心进行下一步的动作,如果 demo 都跑不起来,或者自己摸索写代码,或者先看 USB 基本概念,结果看到最后, 发现一点都看不懂,概念好多,根本记不住,从而丧失对 USB 的兴趣。因此,先跑 demo 非常重要。下面我将给大家罗列目前支持的 demo 仓库。

基于 bouffalolab 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_bouffalolab

FOTG210

less than latest

基于 HPMicro 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_hpmicro

CHIPIDEA

less than latest

基于 esp32s2/s3/p4 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_esp32

DWC2

less than latest

默认 demo 采用组件库安装的形式,在 https://components.espressif.com/ 中搜索 cherryusb 即可。也可使用官方 idf 仓库下的 cherryusb demo。

ESP-Registry 可以参考官方文档,推荐使用 vscode + esp-idf 的开发环境。

  • ctrl + shift + p 选择 ESP-IDF 欢迎界面,然后选择 Component mananger

../_images/esp1.png
  • 找到 cherryusb 并安装

../_images/esp2.png
  • 打开 menuconfig,并打开 cherryusb 的配置,根据实际情况选择主机或者从机模式

../_images/esp3.png
../_images/esp4.png

基于 Phytium 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://gitee.com/phytium_embedded/phytium-free-rtos-sdk

PUSB2/XHCI

equal to v1.4.0

基于 Essemi 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_es32

MUSB

less than latest

基于 Artinchip 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://gitee.com/artinchip/luban-lite

AIC/EHCI/OHCI

less than latest

基于 Kendryte canmv-k230 系列(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/k230_sdk

DWC2

less than latest

基于 NXP MCX 系列芯片

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_mcx https://github.com/RT-Thread/rt-thread/tree/master/bsp/nxp/mcx

CHIPIDEA/kinetis

less than latest

基于 SiFli SF32 系列芯片(官方 SDK 支持)

Repo url

USB IP

Version

https://github.com/OpenSiFli/SiFli-SDK

MUSB

less than latest

基于 RP2040/RP2035 芯片(官方 SDK 即将支持)

Repo url

USB IP

Version

https://github.com/CherryUSB/pico-examples https://github.com/CherryUSB/pico-sdk

RP2040

less than latest

基于 Actionstech 系列芯片(官方 SDK 支持)

Not opensource, 请联系 Actionstech 官方

基于 ST 系列芯片

Repo url

USB IP

Version

https://github.com/CherryUSB/cherryusb_stm32

DWC2/FSDEV

less than latest

默认提供以下 demo 工程:

  • F103 使用 fsdev ip

  • F429 主从使用 USB1, 引脚 pb14/pb15, 默认从机没有开启 DMA 模式

  • H7 设备使用 USB0, 引脚 pa11/pa12,没有开 DMA 模式。主机使用 USB1 ,引脚 pb14/pb15,并且需要做 nocache 处理

demo 底下提供了 stm32xxx.ioc 文件,双击打开,点击 Generate Code 即可。

Caution

生成完以后,请使用 git reset 功能将被覆盖的 main.cstm32xxx_it.c 文件撤回,禁止被 cubemx 覆盖。

涵盖 F1/F4/H7,其余芯片基本类似,不再赘述,具体区别有:

  • usb ip 区别:F1使用 fsdev,F4/H7使用 dwc2

  • dwc2 ip 区别: USB0 (引脚是 PA11/PA12) 和 USB1 (引脚是 PB14/PB15), 其中 USB1 默认全速,可以接外部PHY 形成高速主机,并且带 dma 功能

  • F4 无 cache,H7 有 cache

如果是 STM32F7/STM32H7 这种带 cache 功能,需要将 usb 使用到的 ram 定位到 no cache ram 区域。举例如下

cpu_mpu_config(0, MPU_Normal_NonCache, 0x24070000, MPU_REGION_SIZE_64KB);

对应 keil 中的 sct 脚本修改:

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM2 0x24000000 0x00070000  {  ; RW data
.ANY (+RW +ZI)
}
USB_NOCACHERAM 0x24070000 0x00010000  {  ; RW data
*(.noncacheable)
}
}

USB Device 移植要点

  • 使用 stm32cubemx 创建工程,配置基本的 RCC、UART (作为log使用)

../_images/stm32_1.png
../_images/stm32_2.png
  • 如果使用 fsdev ip,勾选 USB 。如果使用 dwc2 ip,勾选 USB_OTG_FS 或者勾选 USB_OTG_HS。开启 USB 中断,其他配置对我们没用,代码中不会使用任何 st 的 usb 库。

../_images/stm32_3_1.png
../_images/stm32_3_2.png
  • 配置 usb clock 为 48M

../_images/stm32_4_1.png
../_images/stm32_4_2.png
  • 选择好工程,这里我们选择 keil,设置好 stack 和 heap,如果使用 msc 可以推荐设置大点,然后点击 Generate Code

../_images/stm32_5.png
  • 添加 CherryUSB 必须要的源码( usbd_core.cdwc2/usb_dc_dwc2.c 或者是 fsdev/usb_dc_fsdev.c ),以及想要使用的 class 驱动,可以将对应的 class template 添加方便测试。

../_images/stm32_6.png
  • 头文件该加的加

../_images/stm32_7.png
  • 复制一份 cherryusb_config_template.h,放到 Core/Inc 目录下,并命名为 usb_config.h

../_images/stm32_8.png
  • 如果使用 fsdev ip,(V1.5.0 开始需要增加 fsdev/usb_glue_st.c) 在 usb_config.h 中实现以下宏,具体数值不同芯片不一样:

#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
  • 编译器推荐使用 AC6。勾选 Microlib,并实现 printf ,方便后续查看 log。

../_images/stm32_10.png
../_images/stm32_11.png

Note

以下两个步骤从 V1.5.0 开始不再需要,fsdev/usb_glue_st.c, dwc2/usb_glue_st.c 文件中已经实现

  • 拷贝 xxx_msp.c 中的 HAL_PCD_MspInit 函数中的内容到 usb_dc_low_level_init 函数中,屏蔽 st 生成的 usb 初始化

../_images/stm32_12.png
../_images/stm32_14.png
  • 在中断函数中调用 USBD_IRQHandler,并传入 busid

../_images/stm32_13.png
  • 如果芯片带 cache,cache 修改参考 cache 配置修改 章节

  • 调用 template 的内容初始化,并填入 busid 和 USB IP 的 reg basebusid 从 0 开始,不能超过 CONFIG_USBDEV_MAX_BUS

../_images/stm32_15.png

USB Host 移植要点

前面 6 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port (引脚是 PB14/PB15),所以 fs port (引脚是 PA11/PA12)不做支持(没有 dma 你玩什么主机)。

  • 添加 CherryUSB 必须要的源码( usbh_core.cusbh_hub.cusb_hc_dwc2.cusb_glue_st.c 以及 osal 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 usb host.c 添加方便测试。

../_images/stm32_16.png
  • 编译器推荐使用 AC6。勾选 Microlib,并实现 printf ,方便后续查看 log。

../_images/stm32_10.png
../_images/stm32_11.png
  • 复制一份 cherryusb_config_template.h,放到 Core/Inc 目录下,并命名为 usb_config.h

Note

以下两个步骤从 V1.5.0 开始不再需要,fsdev/usb_glue_st.c, dwc2/usb_glue_st.c 文件中已经实现

  • 拷贝 xxx_msp.c 中的 HAL_HCD_MspInit 函数中的内容到 usb_hc_low_level_init 函数中,屏蔽 st 生成的 usb 初始化

  • 在中断函数中调用 USBH_IRQHandler,并传入 busid

../_images/stm32_19.png
  • 链接脚本修改参考 主机链接脚本修改 章节

  • 如果芯片带 cache,cache 修改参考 cache 配置修改 章节

  • 调用 usbh_initialize 并填入 busid 和 USB IP 的 reg base 还有 event_handler 可缺省为NULL, busid 从 0 开始,不能超过 CONFIG_USBHOST_MAX_BUS

  • 启动线程

../_images/stm32_18.png