
1.树莓派 Pico 的 USB 外设概要信息树莓派 Pico 的 RP2040 芯片包含一个 USB 2.0 控制器可以作为任何一种方式操作一个全速设备12Mbps一个可以与低速1.5Mbps和全速设备通信的主机包括连接到一个 USB 集线器的多个下游设备RP2040 芯片内部集成了一个 USB 1.1 PHY 芯片USB 控制器与芯片的 DP(D)和 DM(D-)引脚接口通过 PHY 芯片相连接。USB 控制器的硬件实现了了 USB 物理层、数据链路层和一部分事务层的功能这意味着程序员不需要手动处理复杂的 USB 协议细节。而是将重心放在以下工作上配置控制器参数,如设备地址、端点等提供数据缓冲区,供控制器收发数据响应控制器的中断事件,如数据传输完成、端点状态变更USB 控制器有 4kB 的 DPSRAM用于存储 USB 设备的配置信息和数据缓冲区。USB 控制器可以工作于两种工作模式设备模式USB 2.0 兼容的全速设备12Mbps它支持最多 32 个端点在输入和输出方向上分别为 0 → 15该设备支持控制、等时、批量和中断端点类型并支持双缓冲在 DPSRAM 中有 3840 字节的可用缓冲空间相当于 60 × 64 字节的缓冲区主机模式可以与全速12Mbps设备和低速1.5Mbps设备进行通信它可以通过 USB 集线器与多个设备进行通信包括连接到全速集线器的低速设备设备可以在硬件中轮询多达 15 个中断端点中断端点由集线器用于通知主机连接/断开事件鼠标用于通知主机移动等USB 外设结构如下可以看到USB 外设主要由以下几个部分组成集成的USB PHY芯片负责实现 USB 物理层协议,包括电气特性、信号编码、差分传输等提供了 USB DP 和 DM 引脚与控制器数字逻辑之间的电气接口USB PHY 驱动 DP 和 DM 引脚发送数据并对任何传入数据进行差分接收USB PHY 向线路状态检测模块提供单端和差分接收数据USB 控制器负责实现 USB 设备端的协议栈和端点管理负责数据的接收和发送以及控制信号的生成和解析缓冲区存储器DPSRAM 用于存储控制寄存器和数据缓冲区USB 控制器有 4kB4096 字节的 DPSRAM双端口 SRAMDPSRAM 可以作为 32 位宽度的内存访问地址为 USB 控制器的地址 00x50100000DPSRAM 支持 8/16/32 位访问但不支持设置/清除别名数据缓冲区通常为 64 字节长对于 Isochronous 同步传输方式最大缓冲区大小为 1023 字节对于其他传输方式每个缓冲区的最大大小为 64 字节USB 控制器中的 DPSRAM 应被视为异步的而不是原子的它是一个双端口 SRAM意味着处理器有一个端口来读写内存USB 控制器也有一个端口来读写内存。这意味着处理器和 USB 控制器可以同时访问同一个内存地址。一个可能正在写入另一个可能正在读取。如果控制器在读取内存时处理器正在写入内存可能会得到不一致的数据。必须小心避免这种情况线路状态检测模块定义并检测几种线路状态总线重置、连接、挂起、恢复、数据 1、数据 0 等线路状态检测模块有几个状态机来检测这些状态并将事件信号通知给其他硬件组件USB 中没有共享时钟信号因此 RX 数据必须由内部时钟采样USB 全速的最大数据速率是 12Mbps。RX 数据以 48MHz 的速度采样给出 4 个时钟周期来捕获和过滤总线状态线路状态检测模块将过滤后的 RX 数据分发到串行 RX 引擎接收引擎串行接收引擎负责解码由线路状态检测模块捕获的接收数据。它生成以下信息入站数据包的 PIDPacket Identifier入站数据的设备地址 address入站数据的设备端点 endpoint数据字节串行接收引擎还通过对入站数据进行 CRC 校验来检测 RX 数据中的错误。任何错误都会信号通知其他硬件块并可能引发中断如果在主机模式或设备模式下在数据包传输过程中断开 USB 电缆硬件会引发错误发送引擎串行发送引擎是串行接收引擎的镜像。它连接到当前活动的控制器无论是设备还是主机。它创建 TOKEN 和 DATA 数据包包括计算 CRC并在总线上传输它们2.软件控制方法对于 MicroPython 而言它将 USB 设备划分为以下两种“Runtime” USB 设备:使用 Python API (USBDevice类)在 MicroPython 启动后定义需要在运行时配置和激活。“Built-in” USB 设备:编译到 MicroPython 固件中,始终可用通常包括 USB-CDC (串口) 和可选的 USB-MSC (大容量存储)开箱即用,无需额外配置。MicroPython 提供了用于实现 USB 设备驱动的底层 Python API 的 USBDevice 类构造函数:USBDevice是一个单例类,每次调用构造函数都返回相同的对象引用主要方法:config()方法用于配置 USB 设备的描述符和回调函数active()方法用于激活和停用 runtime USB 设备builtin_driver属性用于获取/设置内置 USB 驱动配置remote_wakeup()方法用于唤醒处于挂起状态的 USB 主机submit_xfer()方法用于提交非控制传输stall()方法用于设置和获取端点的 STALL 状态常量:BUILTIN_NONE,BUILTIN_DEFAULT,BUILTIN_CDC,BUILTIN_MSC,BUILTIN_CDC_MSC代表不同的内置 USB 驱动配置遗憾的是根据如下链接中的回答我们可以看到对树莓派 Pico 来说无法像使用 STM32 芯片的 PyBoard 一样使用 USBDevice 类控制Runtime USB 设备https://github.com/micropython/micropython/issues/6811但是联想到我们在介绍 REPL 交互式解释器中内容在树莓派 Pico 上,MicroPython 固件默认包含了内置的 USB-CDC 设备驱动,提供了一个虚拟的串口通信通道这个 USB-CDC 设备是集成在 MicroPython 固件中的Built-in设备,无需额外的配置就可以使用。这意味着我们可以使用该虚拟串口配合系统输入输出就可以完成 USB 数据传输。