USB1.0-> 1.5Mb/s Low-Speed 12Mb/s Full-Speed
USB2.0-> 480Mb/s High-Speed
特点 : 轮询总线,由Host发起所有的数据传输
鲁棒性 :
USB系统只有一个主机,Host 通过Host controller与Device交互; 检测USB设备插拔;
管理Host和Device之间的控制流,数据流; 收集USB总线状态和活动数据信息; 为连接USB总线的设备供电;
A型 B型 Mini型
差分传输模式
两根数据线D+ D- : 差分信号1 : D+ > 2.8V,D- < 0.3V ; 差分信号0 : D- > 2.8V,D+ < 0.3V;
J状态 K状态
低速 D+为’0’ D-为’1’ 为J状态, K状态相反
全速 同高速
高速 D+为’1’ D-为’0’ 为J状态, K状态相反
SE0状态
D+为’0’ D-为’0’
IDEL状态
低速 空闲状态为’K’状态
全速 空闲状态为’J’状态
高速 空闲状态为SE0状态
针对全速模式
reset信号
主机和设备通信前会发送reset信号来把设备配置到默认的未配置状态.
SE0状态保持10ms
resume信号
20ms的K状态 + 低速EOP
suspend信号
3ms以上的J状态
SOP信号
从IDLE状态切换到K状态
EOP信号
持续2位时间的SE0信号,后跟随1位时间的J状态
SYNC信号
3个重复的K ,J状态切换, 后跟随2位时间的K状态
主从结构
主机 : Host
从机 : Device 分为USB Function和USB HUB
星型拓扑结构
以HOST为顶层,以HUB为中心,HUB串联级数最多5层
数据节点
层级
特征
端点
管道
Host Softwarw的buffer与设备 Endpoint之间的数据搬运模型;
同端点配套,意味着其存在一个Host对Device的默认控制管道, 在上电和总线复位时有效, 用于Device鉴别和配置;
分类
流管道
数据传输无USB定义结构, first in first out, 通信流总是单向的;
信息管道
主机向USB设备发送请求,随后进行数据传输,最后进行传输状态确认, 数据中加入USB定义格式以用来区别请求/数据/状态,允许双向数据流;
同一管道支持一种类型的数据传输,所以需要多个管道完成数据交换,根据传输类型定义可包含的事务类型;
Device(具体参见USB2.0 Table 9-8)
Device_Qualifier
Configuration
Other_Speed_Configuration
描述高速设备的配置
如果以其他速率运行,其结构与配置描述符相同
Interface
Endpoint
String
没有设备连接主机时主机的D+ D-为’0’总线处于SE0状态,此状态持续一段时间,主机认为断开;
设备连接主机时,主机检测到相应数据线拉高,认为设备连接,此时主机必须在复位设备前采样数据线判断设备速度;
全速/高速 D+上拉
低速 D-上拉
连接状态
设备接入总线系统中状态依据规范
上电状态
设备通过配置描述符报告其电源功能
根据设备供电选项上游端口进行对应供电策略
默认状态
上电后不进行任何响应,直至复位信号到来
接到复位信号后,使用默认地址对设备进行寻址
此状态完成后设备在正确的速度下进行操作
地址状态
所有USB设备在加电复位后都使用缺省地址
每一个设备在连接或复位后由主机分配一个唯一的地址
USB设备处于挂起后保持此地址不变
USB设备支队默认通道(pipe)请求发生响应,而不管设备是否已经分配地址或者使用默认地址
配置状态
USB设备正常使用前,必须正常配置
设备角度
使用一个非零配置值正确处理SetConfiguration()请求
配置一个器件或者改变一个可变的设备设置会使与这个相关接口的端点的所有状态与配置值被设为缺省值;
包括正在使用的data toggle的end point data taggle被设置为DATA0
挂起状态
USB设备在探测不到总线传输时自动进入挂起状态,
USB保持本身的内部状态,包括地址及配置
USB设备连接到主机或拔出时,主机通过枚举过程来管理与识别,总线枚举过程经历如下几个步骤
供电 -> 复位 -> 获取DeviceDescriptor前8个字节 -> 复位 -> 分配地址 -> 获取Device Descriptor -> 获取String Descriptor -> 配置
检测电压变化,报告给主机
HUB检测到有电压变化,利用自己的中断将信息反馈给主机
主机探寻设备详细信息
主机通过查询HUB确认此次变化的详细种类
发送Get_Port_Status()请求给hub
Hub检测所插入的设备是高速还是低速
hub通过检测USB总线空闲(IDLE)时的差分线电平来判断所连接设备的速度类型
接收Get_Port_Status()请求后回复速度类型
此操作必须先于复位操作
hub复位设备
主机得知新设备连接,至少等待100ms以等待插入操作及设备电源稳定
之后向hub发送Set_Port_Feature()请求 让hub复位其管理的端口
hub驱动 D+D-为0以复位设备
Host检测所连接的全速设备是否支持高速模式
高速设备在初始时默认全速状态
是否支持取决于设备的上拉电阻切换及总线电流(参考中文网)
HUb建立设备与主机之间的信息通道
主机不断发送Get_Port_Status请求来查询是否复位成功
主机发送Get_Descriptor请求,获取设备描述符
默认管道(Default Pipe)在设备一端视为端点0,此时发送的请求是默认地址0,端点0
设备描述符的第8字节代表设备端点0 的最大包大小
当完成第一次控制传输后,系统会要求hub对设备及性能再次复位,以使设备进入一个确认状态
主机给设备分配地址
主机控制器通过Set_Address请求向设备分配一个为唯一地址, 设备进入地址状态,之后启动新地址
主机获取设备的信息
主机再次发送Get_Descriptor请求到新地址读取设备描述度
主机给设备挂载驱动
主机通过解析描述符获取信息,之后选择一个合适的驱动给设备
之后调用设备模型提供的device_add将设备添加到USB总线的设备列表
设备驱动选择一个配置
驱动根据前面设备回复的信息,发送Set_configuration()请求来正式确定设备的工作配置
设备处理处于配置状态(Configured),设备使能其各个接口
供电;
总线传输数据以包(Packet)为基本单位, 上层称为事务(transaction) 由不同的包组成, 之后组成一次transfer
域组包->包组事务->事务组传输
一个包分为不同的域,不同类型的包含义不同;
但都以同步域SYNC开始,紧跟标识符PID,并以EOP结束符结束
SOP包起始位同步域的一部分
EOP界定符和SYNC等都是通过电气特性描述,扎包工具并能抓到
PID域(8bit)
地址域(11bit)
端点域(4bit)
帧号域(11bit)
数据域(n bytes)
控制传输
HS:64 FS:64 LS:8
批量传输
HS:512 FS:64 LS:N/A
中断传输
HS:1024 FS:64 LS:8
同步传输
HS:1024 FS:1023 LS:N/A
CRC域
token CRC
G(X) = X^5+ X^2 + 1
data CRC
G(X) = X^16+ X^15+ X^2 + 1
包类型
令牌包
OUT
通知设备将要输出一个数据包
IN
通知设备返回一个数据包
SETUP
只用在控制传输中,通知设备将要输出一个数据包
与OUT区别在于只是用DATA0数据包,
且只能发送Device的控制端点
SOF
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B6mM3gV3-1649168263498)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/5_sof.png)]
在每帧开始时以广播的形式发送,USB主机会对当前帧号进行统计,每次帧开始前通过SOF包发送帧号;
主机以全速总线每 1.00ms±0.0005ms 和高速总线 125us±0.0625us 的标称速率发出
数据包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kst98ezy-1649168263499)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/6_data.png)]
握手包
handshake | describe |
---|---|
NAK | 设备暂时没有好接受数据或发送数据 |
STALL | 设备不能用于传输 |
YET/ERR | 仅用于高速传输,设备没有准备好或出错 |
CK | 传输正确完成 |
事务类型 | describe |
---|---|
setup事务 | 主机用来设备发送控制命 |
数据输入事务(IN) | 主机用来从设备读取数据 |
数据输出事务(OUT) | 主机用来向设备发送数据 |
控制传输
特点:
突发, 非周期性; 主机软件发起的"请求/响应"通信, 通常用于"命令/状态"操作
同步传输
特点:
主机与设备之间的定期, 连续通信, 通常用于对时间敏感的数据; 此传输类型保留了封装在数据中的时间概念
中断传输
特点:
低频,有限延迟通信 数据量小不连续,但实时性要求很高的传输
约束:
中断管道
流式管道->单向数据传输, 端点描述符给定中断管道的通信流的方向
传输包约束
中断管道端点,指定它将发送或接收的最大数据有效载荷 LS: 8bytes FS:64bytes HS:1024Bytes
USB系统软件确定配置期间用于中断管道的最大数据有效负载大小 此大小在设备配置的整个生命周期保持不变
USB系统软件确认最大负载数据后确认总线时间,在保证总线时间能够容纳最大数据负载后建立管道
端点传输数据时必须始终保持数据量不超过wMaxPacketSize 值,Device可以通过大于wMaxPacketSize的中断管道传输数据
Client SW可以通过IRP(See I/O Requset Packet)来接收数据,当数据拆包为多个事务时,Client SW设置缓冲实现
传输数据包完成标志
已准确传输预期的数据量
数据有效负载大小小于最大负载,或数据包长度为0
中断传输完成后主机控制器退出当前IRP,进入下一IRP
如实际传输负载大于预期,此中断IRP将"aborted/retired",并且管道将停止接收IRP
高速默认接口传输最大负载不能超过64Bytes
总线接口约束
批量传输
特点
非周期性,大数据包突发通信 ; 通常用于可以使用任何可用带宽的数据
数据量大但对时间要求不高的传输
采用 "令牌包 + 数据包 + 握手包"的传输形式 令牌包指定数据去向或者来源的设备地址和端点 握手包表示数据传输结果
中断传输
IN事务(Host->Device) -> Data(Device->Host) -> ACK(Host->Device)
OUT事务(Host->Device) -> Data(Host->Device) -> ACK(Device->Host)
同步传输
IN事务(Host->Device) -> Data(Device->Host)
OUT事务(Host->Device) -> Data(Host->Device)
两路控制器信号独立;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yi61nbUJ-1649168263503)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/9_block.png)]
每个控制控制器DMA传输通过AHB总线连接到PS片内互联;
控制及状态寄存器由APB映射到系统内存空间进行系统编址;
两个USB控制器有独立的复位信号及输出到GIC的中断信号;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u3U2oB9S-1649168263504)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/10_contr.png)]
DMA, Protocol Engines, Context and FIFOs
DMA引擎与协议引擎一起处理endpoints,periodic elements,queue heads,等其他传输描述符;
软件将数据结构写入系统内存,DMA引擎获取这些数据结构并将其复制到控制器的本地双端口RAM;
控制器在处理数据结构时读取和写入DPRAM中的数据结构;
当传输完成时,描述符通过DMA引擎返回内存;
除数据结构的上下文信息,控制器同时使同DPRAM来实现TX RX 的FIFO;
这些FIFO为系统内存和USB实时传输提供缓冲;
FIFO的使用方式跟随模式变动, 主机模式下通过DPRAM在每个方向上保持单个数据信道;
设备模式下,针对每个活动设备端点维护RX和TX数据FIFO通道,并且FIFO通道可以异步和实时操作;
Port Transceiver Controller
端口收发器提供 暂停/恢复,并且用于设备模式,chirp 控制功能(两次上电reset后的chrip K信号);
端口控制器控制8位的数据总线传递到8位的ULPI;
USB控制器的整个后端与PHY的60 MHz USB时钟同步工作;
ULPI(USB Low Pin Interface) Link Wrapper
协议引擎包括一个类似与UTMI+的内部总线;
ULPI wrapper 在此总线和ULPI接口之间提供一座桥梁,对用户透明;
ULPI Wrapper传递数据包并解释RX命令以及发送 TX命令;
ULPI Rx/Tx Commands
Rx命令由PHY启动以设置状态位,从而时软件能够查看PHY事件,这些指令设置控制器状态位;
Tx命令由软件通过寄存器写入来启动,以控制PHY功能,这些指令由ULPI规范定义;
Programmable Timers
两个控制器有独立的通用定时器用于生成超时或测量时间活动;
控制器用定时器生成帧(微帧)间隔并为Host控制器调度程序生成选通信号;
Software Programming Interface
除系统内存中维护数据和缓冲区结构,软件还读取和写入控制和状态寄存器;
控制器可以生成由DMA和协议引擎活动,PHY和其他控制器功能引起的中断;
Control and Status Registers
控制和状态寄存器包括常量,配置和 操作/状态(ECHI Host模式)兼容性以及非ECHI功能(Device,OTG);
Clock and reset
ULPI接口和协议引擎工作在通过ULPI接口输入的60MHz下;
AHB总线工作在CPU_1x;
CPU_1x和60MHz的跨时钟域通过DPRAM实现;
控制器复位: PS 复位系统(全控制器复位), usb.USBCMD[RST] bit位(部分控制器复位用于OTG);
ULRL PHY 复位: GPIO输出控制信号;
USB Bus 复位:OTG模式下的自动复位 , USB复位控制传输;
软件管理控制器自身的配置和控制 以及 用于USB事务的一组一致的数据结构和内存缓冲区;
两种数据结构模型: data 和 host;
三种控制模式: Host, Device, OTG, OTG使用主机或器件模式;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-etXoee8R-1649168263505)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/11_endpoint.png)]
响应Host请求,DCD(Device Controller Driver)设置一个端点描述符并管理端点的实时需求;
内存和ULPI之间的高速数据传输由控制器使用Queue Head和传输描述符进行管理;
每次传输的结果都由DCD进行确认并执行相应的操作;
Host Mode
Device Controller包括一个简单描述符模型用来快速响应主机请求;
12个端点每一个都有2个 device Queue Heads(dQH),一个用于IN事务,一个用于OUT事务,共有24个设备dQH;
使用一个dQH和≥1个的设备传输描述符(dTD)来定义一次数据传输;
Link-List Concept
Host和 Device控制器使用链表描述符来管理内存buf的双向传输流;
首TD(Transfer Descriptors)指向Queue Head,具体结构如下:
数据传输
主机模式下,数据结构由EHCI规范定义, 表示由主机控制器执行的而周期行异步传输队列,包括允许控制器将数据包发送到FS/LS设备,该设备位于外部的Hs Hub或根Hub的下游;
主机模式使用队列头 (QH), 队列元素传输描述符 (QTD), 等时传输描述符(ITD), 分割事务等时传输描述符 (SITD)和周期帧跨越横向节点(FSTN)数据结构;
器件模式,数据结构较为简单,由链表形式的设备队列头(dQH)和设备传输描述符(dTD)组成;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XDrYUHYN-1649168263509)(14_dma.png)]
协议引擎解析令牌包,生成相应包响应,以及执行错误检测功能;
引擎执行所有的错误检查, 检查字段生成,格式化总线上的所有的握手,ping,数据响应包,并根据基于USB规范的时间范围生成所需的信号;
协议引擎功能
令牌状态机跟踪总线上的所有令牌并根据令牌上的地址和端点信息进行过滤;
CRC5/CRC16 生成器/校验器电路检查并生成令牌和数据包的CRC域;
数据和握手状态机生成USB所需的任何响应,并将数据包数据通过DPRAM传送到DMA控制器;
间隔定时器提供识别重要总线定时事件的定时选通: 总线超时间隔,微帧间隔,帧开始间隔,总线复位,恢复和暂停间隔;
向DMA引擎报告所有传输状态;
此定时器要与控制器间隔定时器区分,此定时器为两个可编程的独立定时器,用于生成超时或测量与时间相关的活动;
该定时器受控于其自身的控制及装载寄存器: usb.GPTIMERxCTRL and usb.GPTIMERxLD ;
控制寄存器包含定时器配置及一个数据字段,可以查询运行计数值,粒度1us;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0LmDjLm-1649168263511)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/14_stack.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JLQwDDvW-1649168263513)(15_mode.png)]
控制器处于控制模式时, 软件启动其控制端点, 根据设备的功能准备描述符并准备必要的端点;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6JLoJJe-1649168263514)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/16_state.png)]
软件负责维护状态变量以区分默认 FS/HS状态和地址/配置状态;
根据USB2.0协议,根据设备枚举过程中的配置更改相应地址及配置状态;
进入地址状态后,设备地址寄存器由DCD(Device Controller Dirver)操作;
进入配置状态后操作端点控制寄存器并初始化关联的队列达到配置所有需使用的端点的目的;
Host下发初始化指令复位总线;
当检测到总线复位时,设备控制器硬件重新协商连接速度(LS\FS\HS)并将设备地址复位,并通过中断通知DCD,接收到复位后,除控制端点(0端点)外禁用所有端点,并任何已启动的事务都被设备控制器取消;
DCD接收到复位时必须执行如下任务:
Device Controller Reset
Port Change Detect(端口探测)
检测到端口变化后,器件达到默认状态,同时DCD读 PORTSC1寄存器确认器件的速率模式; 此时设备控制器已经就已经进入正常工作模式,根据USB2.0协议进行事务响应;
端点链表描述符组成器件端点的数据结构,软件为其提供初始化并控制;
device 控制器存在两种类型描述符: device Queue Head(dQH) ,device Transfer Descriptor(dTD);
DMA引擎使用Link-List描述符来响应来自host的端点包请求;
DCD维护每个队列头的dTD链表的头尾指针;因为dQH只维护当前工作dTD和下一个执行的dTD;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VdVUSXSm-1649168263516)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/17_device_link_list.png)]
Descriptor and Data Flow
每个端点一个Queue Head;
根据上述章节所描述的内容,驱动层在初始化时初始端点并设置dQH,dQH维护当前执行dTD及下一次dTD,这个结构加上Tx_Buf组成发送数据结构,同时驱动层为达到保护内存的目的去维护dTD的头尾;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Sq78SXf-1649168263517)(18_data_flow.png)]
端点为USB设备唯一可寻址的部分,其作用在于Host和Device的信道中获取或接受数据;
端点地址由端点编号和端点方向共同确定;
Host和Device端点之间为数据管道,Device 的端点0始终适用于设备发现和枚举的控制端点; 端点类型与传输类型一一对应;端点数量最大12个(针对Zynq);
DCD可以启动, 禁用, 配置端点类型, 每个端点方向独立存在,即可以在每个方向上配置不同的行为; eg: endpoint1 的IN和OUT可以为不同的端点类型;
每一个端点方向在内存中需要一个dQH, 这意味着最高需要24个dQH来描述
硬件复位后所有非0端点都是禁用且未初始化的;
DCD通过写入配置寄存器 usb.ENDPTCTRLx 使能和配置每一个端点;
每个32位 usb.ENDPTCTRLx 分为上半部分和下半部分, 下半部分用于接收或OUT端点,上半部分用于配置相应的发送或IN端点; 控制端点必须在usb.ENDPTCTRLx寄存器的上半部分和下半部分配置相同否则为未定义定位;
Stall 参考USB2.0 chapter 8.4
如下两种情况下Device需要向Host返回STALL:
Function Stall(功能停顿),由DCD基于USB2.0实现停顿, 功能停顿仅限于非控制端点, 可以通过设置与给定端点和给定方向关联的usb.ENDPTCTRLx[TXS]停顿位在Device Controller中启动. 在启动条件下, 控制器将继续向发生在相应端点和方向上的所有事物返回STALL响应,直到端点停止位被DCD清除;
Protocol Stall(协议停顿),用于控制端点, 并在新的控制事务(设置阶段)开始时由设备控制符自动清除. 启动协议停顿时,DCD应成对启动停顿位(IN and OUT),对usb.ENDPTCTRLx 寄存器一次写入保证两个停止位同时设置;
注: 任何写入usb.ENDPTCTRLx 寄存器的操作必须保留端点模式字段;
Data Toggle 参考USB2.0 chapter 8.6
数据切换对应到USB2.0 即为包域的Data 0/1 切换及一系列的机制跳转;
DCD可以复位数据翻转状态位, 并通过usb.ENDPTCTRLx [TXR]寄存器中的数据翻转位写入1来使设备控制器中的数据翻转序列复位,这个操作只有在 配置/初始化/从STALL条件返回 时需要执行;
所有传输由USB Host发起,Device在一定时间范围内进行响应;
主机无法精确预测每个单个管道的顺序去向设备控制器发送请求, 因此无法为设备控制器准备单个数据包来执行,但是 当考虑端点编号和方向时,数据包请求的顺序是可预测的, eg:端点3(传输方向)配置为bulk pipe,那么可预期主机向该端点发送IN请求;
所有传输由USB Host发起,Device在一定时间范围内进行响应;
主机无法精确预测每个单个管道的顺序去向设备控制器发送请求, 因此无法为设备控制器准备单个数据包来执行,但是 当考虑端点编号和方向时,数据包请求的顺序是可预测的,
eg:端点3(传输方向)配置为bulk pipe,那么可预期主机向该端点发送IN请求;
Prime and Flush Endpoints
器件控制器的实现方式为预测主机对每个端点或方向所发出的请求.;
准备响应总线上的主机发起的事务发送或接受数据的设备控制器的过程称为"prime"端点;
"flush"用于清除排队执行的数据包的操作;
flushing一个控制器端点会导致此端点 de-primed(意味着端点必须完成重新初始化才能继续使用);
启动发送端点会触发控制器获取dQH指向的事务的dTD;取到dTD后其会被复制到dQH中,直到Device Controller完成dTD描述的传输;从dQH覆盖区域中复制dTD允许Device Controller获取处理来自主机的请求所需的操作而不需要遵循dTD链表,从接受主机请求的dQH开始;
设备加载dTD后,数据包中的前导数据存储在设备控制器的FIFO中; 此FIFO被拆分为虚拟通道,已达到存储多
端点前导数据的摸底,拆分量取决于初始化时配置的端点量;
启动请求完成后, 端点状态在ENDPTSTATUS寄存器中报告. 对于已启动的发送端点,device controller就可以进行IN事务的响应且严格满足USB总线周转时间;
由于控制器FIFO中只进行前导数据的存储,因此设备控制器需要在事务开始后填充前导数据,同时考虑系统内存总线对FIFO大小的影响;
DCD层面接收端点和发送端点一致;
设备控制器层面,其与发送端点区别在于前导数据包数据没有数据移动, 因为数据是从主机接收;
接收FIFO不分通道且大小固定;
中断端点和批量端点操作一致;
所有有效的传输事务通过BULK管道, 端点准备好进行数据传输, 未准备全部返回NAK;
Device Controller会收回dTD当传输描述符中描述的包完成时, 每个dTD描述了根据USB协议的变长协议计算的需传输的N个报文,设备控制器根据最大装载和需传输总字节数计算USB发送和接收数据包的数量和长度,计算公式如下:
N = INT(Number of Bytes/Max. Packet Length) + 1; (With Zero Length Termination dTD.ZLT == 0)
N = MAXINT(Number of Bytes/Max. Packet Length); (With Zero Length Termination dTD.ZLT == 1)
注: dQH.Mult 域在中断 , 批量, 控制传输中必须设置为 “00”
关于dTD.ZLT 在批量及控制传输中的操作:
默认值 = 0;意味着Zero Length Termination开启;
满足下列条件时,硬件会自动附加一个零长度数据包:
传输的数据包等于最大数据包长度
dTD已发出所有字段
在此之后,dTD被销毁. 设备在接收时,如果接受到的最后一个包长度等于最大包长度且总字节数为0 ,它将等待来自主机的一个零长度包退出当前的dTD;
dQH.ZLT = 1,意味着Zero Length Termination关闭;
硬件不在自动添加零长度数据包;
在接收时,其不需要零长度的数据包来销毁最后一个数据包等于最大数据包的dTD. 一旦总字节数为0,或收到一个短数据包,dTD自动销毁;
当dTD描述的数据包成功完成时, dTD中的活动位将会清除,并且当中中止位被清除时跟进下一个指针.当设置中止位时,Device Controller会flush 端点并停止对该端点的操作;
在一个数据包未完成时,dQH将指向错误的dTD, 并尝试恢复,恢复手段为清除活动位来重新初始化dQH, 并在尝试重新启动端点之前跟新到下一个dTD指针;
注: 类似握手缺失或CRC失败等数据包级操作控制器会自动重传, 不需要与DCD进行交互;
注:
BS Error->强制位填充错误;
NYET/ACK->NYET除非dTD描述的数据大于最大状态即有剩余的数据包 then ACK(此处对ug585的表述不太理解) 根据抓包判断正常传输返回ACK , 当返回NYET时下次传输Host会在下发OUT事务前先行下发PING包, 那么可以理解为NYET是向主机包括存在下一次接收句柄存在风险(当前包接收成功但没有空间接收下一帧),Host下发PING包确认状态后在下发OUT;
BTO->总线超时;
SYSERR->延迟FIFO大小合适 DCD有相应 此错误不会发生;
dQH用于所有的Device Controller传输的管理, 大小为48Bytes, 在实现时字节对齐至64字节;
在端点启动时,硬件从系统内存中读取dQH和第一个dTD, 并将其覆盖在dQH的2~8 (双字节),如下:
Dword 0 | 端点 特点及容量 |
---|---|
31:30 | Mult. 高带宽管道Multiplier,该字段用于指示每个dTD执行的数据包数量 00: N个数据包 N的取值见chapter C, 非同步传输端点必须设置为 00; 01 : 1个事务, 10 : 2个事务, 11: 3个事务 .同步端点任选 |
29 | ZLT 见chapter C |
28:27 | 保留,设置为0 |
26:16 | 最大装载长度, 对应关联端点的wMaxPacketSize , 最大 0x400 |
15 | 设置时中断, IOS, 被用于控制端点,指示USBINT是否响应接收 |
14:0 | 保留 设置为0 |
Dword 1 | 当前dTD指针 |
31:5 | 指向传输覆盖区域中表示的dTD的指针, 在端点启动或队列推进器件该字段由设备控制器修改为下一个dTD指针. 设备控制器使用当前dTD指针来定位正在进行的传输. 此字段仅由设备控制器硬件使用, DCD不能对其进行操作; |
4:0 | 保留 设置为0 |
Dword 2 | 下一dTD指针及中止 dQH Dword:2 dTD Dword:0 |
31:5 | 下一个要处理的dTD的系统内存指针 |
4:1 | 保留 设置为0 |
0 | 中止传输 T; 0->链接到下一个dTD指针, 且地址有效; 1->中止传输,下一个dTD指针域无效 |
Dword 3 | Total Bytes, MultO, and Status dQH Dword:3 dTD Dword:1 |
31 | 保留 设置为0 |
30:16 | Total Byte: 此次传输描述的字节数总量,在事务成功完成时进行递减 DCD能存储最大值为5*4K = 0x5000;(仅当Dword4偏移量为0时); 一般建议最大值取16KB; |
15 | 完成时中断, 指示是否设置USBINT以响应设备控制器完成此dTD |
14:12 | 当前页 , 器件模式保留 |
11:10 | Multiplier 覆盖,用于传输同步数据包, |
9:8 | 保留 设置为0 |
7:0 | 设备控制器使用该字段将单个命令执行状态返回DCD; 此字段包含在此dTD上执行的最后一个事务的状态; Bit[7]活动状态, bit[6]暂定状态 bit[5]数据缓冲区错误状态 bit[3]传输错误状态 其余位保留 |
Dword 4 | 第0页缓冲区指针及当前偏移量 dQH Dword:4 dTD Dword:2 |
31:12 | Buffer Point : 4KB边界对齐的系统内存地址 |
11:0 | 当前偏移量 |
Dword 5 | 第1页缓冲区指针及帧号 dQH Dword:5 dTD Dword:3 |
31:12 | Buffer Point : 4KB对齐的系统内存地址 |
11 | 保留 |
10:0 | 帧号 ,由设备控制器进行写入,以指示分组完成的帧号; 通常用于将分组的相对完成时间关联在ISO端点上; |
Dword 6-8 | 第2-4页缓冲区指针 dQH Dword:4-6 dTD Dword:6-8 |
31:12 | Buffer Point : 4KB对齐的系统内存地址 |
11:0 | 保留, 设置为0 |
Dword 9 | 保留 |
Dword 10 | 设置缓冲区字节 [31:24]->Byte3 , [23:16]->Byte2 , [15:8]->Byte1 , [7:0]->Byte0 |
Dword 11 | 设置缓冲区字节 |
dTD向设备控制器描述给定传输中要 发送/接受 的数据的位置和数量;
实现时对齐到32字节;
DCD不能修改正在活动中的dTD任何字段, next dTD可以;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rnqM1kZS-1649168263521)(https://raw.githubusercontent.com/H-voyager/markdown-photo/main/usb-device/21_dtd.png)]
控制器从内存中读取dQH并链上一个dTD. dTD同样从内存中读取, 并写入dQH的覆盖区;
覆盖区域的7个双字空间代表设备控制器的事务工作空间. 端点准备好后, 设备控制器将把dTD复制到此dQH的这个空间.在传输未完成之前, DCD不能写入队列头覆盖区域或关联的dTD. 传输完成后,设备控制器会将dTD写回系统内存(添加状态结果)并推进队列指针;
如果链表存在后续, 则从内存中取出另外一个dTD并将其写入dQH的传输覆盖区域. 处理完链表,dQH写回系统内存, 端点服务完成.
设备控制器的功能是将内存映射中的请求传输到USB或从USB获取. 设备控制器根据应用层协议对端点进行编程和初始化. 控制器执行一组链表传输控制符,dQH指向,设备控制器执行请求的数据传输.
硬件复位之后,器件在Run/Stop位未置为1处于禁用状态, 在禁用状态下, 为防止放生连接,USB 的D+上拉电阻不活动. 为创建连接,须在设备连接发生之前为控制端点 0 设置dQH. 之后设备启动,并进行USB协议的连接控制进行一系列的操作包括再复位,dQH是设备控制器可以存储转入的设置数据包的前提;
为达到初始化器件的目的,DCD必须执行以下操作:
设置控制器为器件模式, 向usb.USBMODE [CM] 位写10
分配并初始化dQH
非控制端点dQH初始化可以不再启动端点之前初始化,但是一定要在使用端点之前;
向usb._ENDPOINTLISTADDR [31:11] 位写入dQH的头端点列表地址;
使能软件中断
使能Run Mode 设置Run/Stop位
端点功能在于指示DMA引擎在系统内存和TX/RX FIFO之间搬运数据;
每个端点存在两个数据结构: IN 和 OUT ;
设备模式数据结构包括一个dQH和N个dTD, dQH定义数据传输类型并指向第一个dTD,dTD包括指向系统内存缓冲区的系统地址, USB数据在此由DMA进行读写;
存在一个dQH链表对24个dQH建立索引, 为建立一次传输,软件需要去为IN/OUT事务构造dQH和dTD. 软件必须在系统内存中为控制器维护一组一致的descriptors, schedules/lists,data buffers .当端点准备好传输数据时软件启动端点;
设备控制器将相关的dQH和dTD读取到控制器的DPRAM中,DMA及协议引擎进行访问. 当dTD的DMNA完成后, 控制器将"dTD + 传输结果"写回系统内存.
当终止位T = 0(存在下一个dTD),则控制器从系统内存中获取下一个dTD, 否则控制器停止处理端点dQH并将dQH写回系统内存, 在一个较长的链表中,控制器将从系统内存与DPRAM之间反复读写dTD;
初始化dQH
DCD必须只在关联端点未启动且没有未完成的dTD时修改dQH
Operational Model for Setup Transfers
DCD6应对设置传输包进行特殊处理, 设置传输不使用dTD, 而是将来自设置数据包的输入数据存储在dQH的8字节缓冲区内;
从dQH-RX中复制设置缓冲区内容到软件缓冲区;
通过将 1 写入usb.ENDPTSETUPSTAT中写入相应位置来确认设置数据包;
检查来自之前控制传输的未处理数据或者dTD,如果存在,则按照相应规则刷新端点;
传输前需要为端点建立32字节内存对齐的dTD, 在系统内存中开辟8-DWord的一个dTD空间,
DCD必须按照如下规则添加新的dTD:
判断一个链表是否为空: 检查管道是否为空
Link list为空:
Link list不为空:
在初始化dTD并且相关端点已经准备好后,设备控制器将根据Host发起的请求执行传输, 如果设置了完成时中断, DCD将收到USB中断通知,或者DCD可以轮询端点完成寄存器查找dTD的执行状态. 执行dTD后, DCD可以通过状态位判断执行结果;
注: 多个dTD可以在单端点完成通知时完成. 完成通知后,DCD必须检索dTD链表并退出所有已完成的dTD(活动位清除). 通过读取已完成dTD的状态字段,DCD可以通过以下状态位判断传输结果:
Active = 0 & Halted = 0 & Transaction Error = 0 & Data Buffer Error = 0
上述结果之外的所有结果均为失败 ,DCD必须进行相应的措施;
除检查状态为之外,DCD必须读取传输传输字节字段来确认实际传输的字节;
传输完成后, 传输的总字节数减去传输的实际字节数;
对于发送数据包,只有实际字节数达到0 后数据包才为传输完成;
对于接受数据包,Host可能会根据USB的可变数据包协议在传输中发送较少的字节数;
端点 Flushing/de-Priming
当接受到USB设备复位, 发生控制传输中断,DCD必须flush位来对一个或多个端点进行卸载, 应用层面的停止传输同理; 实现步骤如下:
Device Error
控制器不自动handle的包错误如下:
除上表中同步传输外所有的传输类型的所有错误都由控制器处理(数据缓冲区溢出除外)
在初始化dTD并且相关端点已经准备好后,设备控制器将根据Host发起的请求执行传输, 如果设置了完成时中断, DCD将收到USB中断通知,或者DCD可以轮询端点完成寄存器查找dTD的执行状态. 执行dTD后, DCD可以通过状态位判断执行结果;
注: 多个dTD可以在单端点完成通知时完成. 完成通知后,DCD必须检索dTD链表并退出所有已完成的dTD(活动位清除). 通过读取已完成dTD的状态字段,DCD可以通过以下状态位判断传输结果:
Active = 0 & Halted = 0 & Transaction Error = 0 & Data Buffer Error = 0
上述结果之外的所有结果均为失败 ,DCD必须进行相应的措施;
除检查状态为之外,DCD必须读取传输传输字节字段来确认实际传输的字节;
传输完成后, 传输的总字节数减去传输的实际字节数;
对于发送数据包,只有实际字节数达到0 后数据包才为传输完成;
对于接受数据包,Host可能会根据USB的可变数据包协议在传输中发送较少的字节数;
端点 Flushing/de-Priming
当接受到USB设备复位, 发生控制传输中断,DCD必须flush位来对一个或多个端点进行卸载, 应用层面的停止传输同理; 实现步骤如下:
Device Error
控制器不自动handle的包错误如下:
[外链图片转存中…(img-zdzCOdQY-1649168263522)]
除上表中同步传输外所有的传输类型的所有错误都由控制器处理(数据缓冲区溢出除外)