S3C6410 USB枚举过程的工作经验总结

1.有关对比结束阶段的不同点: 
对控制写入阶段:setup--OUT (Data0 | 1)--IN(0长DATA1) 
USB HOST送出IN包,USB Device以0长DATA1 包结束控制写入过程 

对比控制读取过程:setup--IN(Data0 | 1)--OUT(0长DATA1 ) 
USB HOST发出OUT 0长DATA1包以结束控制读取过程 

对于无数据的控制事务:setup--IN(0长DATA1)也是用HOST发IN包Device 
响应0长DATA1包+ ACK以结束无数据的控制事务 

clear feature, set address, set configuration, SYNC Frame均最后将状态设置为 
EP0_STATE_INIT,以USB HOST发出IN包USB Device响应0长DATA1包+ ACK 
结束无数据的控制事务 

==================== 
2.有关IN Token, OUT Token, SETUP Token的置位DAINT情况: 
1):IN Token: 
EP0 IN端点上收到IN token包时按理说当置位:DAINT:1,但实际置位了:DAINT: 
0x1000 即为EP0 OUT位 

2).OUT Token 
See <<S3C6410 OUT包与DATA1对DAINT的影响调试实验报告.txt>> 

3).SETUP Token 
See <<S3C6410 SETPUP包与DATA0对DAINT的影响调试实验报告.txt>> 

======================= 
3. IN|OUT TOken包收到处理过程 : [这里只是初步分析的结果,详细结果见<<S3C6410 OUT包与DATA1对DAINT的影响调试实验报告.txt>> 
+ <<S3C6410 SETPUP包与DATA0对DAINT的影响调试实验报告.txt>> ] 
1).IN|OUT Token收到送入RxFIFO中 
2).GINTSTS的有关RxFIFO Level置位表示收到数据 
3).6410会自动解析所收包的类型,由于IN|OUT Token包的格式为: 
sync IN|OUT addr endp crc5 eop 
4). 所以6410能知道是哪个端点,是IN还是OUT,于是置位相应IN|OUT EP于DAINT中的相应位 
所以利用DAINT就能知道是否收到IN|OUT Token,但要注意DAINTMSK要开,同时GINTSTS RxFLvl也会置位(受GINTMSK En) 
setup包类上,只不过是置位GRXSTSP[PktSts]来表示是否收到setup包 

OUT 的判断: 
OUT包收到后先由6410自动解析处理,同时于GRXSTSP/R中置位表示OUT包到了 
其实这时,还不会置位DAINT中的相应端点,而是要等紧跟其后的DATA1包到了后,DAINT相应端点置位 
同时GRXSTSP/R置位 

======================== 
4.tmc的一个常见错误处理: 
当tmc屏幕上出现DevID USB/VID_0525&PID_A4A7/5&20F5DB59&0&1 is not the VCP DEVICE!提示时 
是占用了同一个com口,在设备管理器中修改其为另一个com口即可 
再停用后,再重新启用即可 
要记得,最好是最后开tmc 

======================= 
5.有关USB 2.0 HS OTG LINK与PHY的组成情况: 
有关USB 2.0 HS OTG Controller由USB 2.0 OTG LINK与USB 2.0 OTG PHY两部份组成, 
PHY Clock 30/48MHz供给这两块芯片 

USB 2.0 PHY ==>AHB Slave 
USB 2.0 LINK==>AHB Master/Slave 

USB 2.0 PHY/LINK均连到AHB Slave,故6410能读写这两个的CSRs,也即只发送控制信号 
而只有AHB Master连到USB 2.0 LINK,故只有USB 2.0 OTG LINK这一路上有Data Transfer,数据传输走AHB 
Master==>USB 2.0 LINK 
Refer : 6410 Spec P 26-2 

======================= 
6.UTMI与Serial Interface: 
OPHYCLK[serial_mode]: UTMI/Serial Interface Select来源于图:P26-2 
UTMI: 是USB 2.0 OTG LINK经UTMI Interface连接至USB 2.0 OTG PHY上 
Serial Interface :指D+,D-上的Data 的传送经USB 1.1 Serial Interface连接至USB 2.0 OTG PHY上 

====================== 
7.不同的传输速率,不同的传输类型其端点描述符的wMaxPacketSize字段配置不同 
LS: Low Speed HS: High Speed FS: Full Speed 
1.对控制传输端点: 
LS: 8B (must) 
FS:8B/16B/32B/64B 
HS:64B(must) 

2.对块传输端点: 

LS: Not Support 
FS:8B/16B/32B/64B 
HS:512B(must) 

3.对中断传输端点: 

LS: <= 8B 
FS: <= 64B 
HS: <= 1024B 

4.对同步传输端点: 

LS: Not Support 
FS: <= 1023B 
HS: <= 1024B 


====================== 
8.6410 USB OTG 部份是三级中断结构: 
第一级:GINTSTS中为USB (IN | OUT)产生了中断 
第二级:依据上一步是IN 或OUT,于DAINT中得到产生中断的Endpoint号 
第三级:依据第二步得到端口号于DIEPINTn | DOEPINTn中判断是什么中断 
处理完中断后,将相应中断Reg中的那位清零,又可准备下一次的该位的中断 
否则,不会响应该位的中断直至此位清零 

====================== 
9. 描述符初始化框架内容列表 
a) Descriptors The structure of descriptors 
Device 
Configuration Interface(0) - Communication Class 
Class-specific IF (Header Functional) 
Class-specific IF (Call Management Functional) 
Class-specific IF (Abstract Control Management Functional) Class-specific IF (Union Functional) 
Endpoint (Interrupt IN) == > 目前暂用Polling 中断位 
Interface(1) - Data Interface Class Endpoint (Bulk IN) 
Endpoint (Bulk OUT) 

a-1) Device descriptor (usbcdc11.pdf 5.1.1 p31) 
bDeviceClass: 0x02 (Communication Class: USB_CLASS_COMM) 
bDeviceSubClass: 0x00 
bDeviceProtocol: 0x00 
idVendor: VID: 0x0525 
idProduct: PID: 0xa4a7 

a-2) Configuration descriptor 
wTotalLength: 0x3e 
bNumInterfaces: 0x02 

a-3) Interface descriptor(0) - Communication Class 
bInterfaceNumber: 0x00 
bNumEndpoints: 0x01 
bInterfaceClass: 0x02 (Communication Class) 
bInterfaceSubClass: 0x02 (Abstract Control Model) 
bInterfaceProtocol: 0x01 (V.25ter, Common AT commands) 

a-3-1) Class specific descriptors a-3-1-1) 
Header Functional Descriptor (usbcdc11.pdf 5.2.3.1 p34) 
bLength: 0x05 
bDescriptorType: 0x24 (CS_INTERFACE) 
bDescriptorSubtype: 0x00 (Header Functional) 
bcdCDC: 0x0110 (CDC spec release number, 1.1) 

a-3-1-2) Call Management Functional Descriptor 
bLength: 0x05 
bDescriptorType: 0x24 (CS_INTERFACE) 
bDescriptorSubtype: 0x01 (Call Management) 
bmCapabilities: 0x01 (only over Communication Class IF / handles itself) 
bDataInterface: 0x01 (Interface number of Data Class interface) 

a-3-1-3) Abstract Control Management Functional Descriptor 
bLength: 0x04 
bDescriptorType: 0x24 (CS_INTERFACE) 
bDescriptorSubtype: 0x02 (Abstract Control Management) 
bmCapabilities: 0x06 (Supports Send_Break, Set_Line_Coding, Set_Control_Line_State, 
Get_Line_Coding, and the notification Serial_State) 

a-3-1-4) Union Functional Descriptor 
bLength: 0x05 
bDescriptorType: 0x24 (CS_INTERFACE) 
bDescriptorSubtype: 0x06 (Union Functional) 
bMasterInterface: 0x00 (Interface number master interface in the union) 
bSlaveInterface0 : 0x01 (Interface number slave interface in the union) 

a-3-2) Endpoint descriptor - (Interrupt IN) EP0:Control EP,此处用Polling 中断位实现 
bmAttributes 0x03 (Interrupt) 
wMaxPacketSize: 0x0010 (16 bytes - more than SerialState response, 10 bytes) 
bInterval: 0x01 (1msec) 

a-4) Interface descriptor(1) - Data Interface Class 
bInterfaceNumber: 0x01 
bNumEndpoints: 0x02 
bInterfaceClass: 0x0A (Data Interface Class) 
bInterfaceSubClass: 0x00 
bInterfaceProtocol: 0x00 (No class specific protocol required) 

a-4-1) Endpoint descriptor (Bulk IN EP1 and Bulk OUT EP 2) 
bmAttributes 0x02 (Bulk) 
wMaxPacketSize: 0x0040 (64 bytes) 
bInterval: 0x00 

--------- 
说明: 

====================== 
10. 对上面的描述符设置的一点说明: 
Standard configuration descriptor 
Attention:此配置支持两个接口:一个用于控制,一个用于数据 
用于控制的:GS_CONTROL_INTERFACE_ID 
用于数据的:GS_DATA_INTERFACE_ID 

USB枚举时会取配置描述符,USB Device将会发送大小为CONFIG_DESC_TOTAL_SIZE 
这部份数据就包含了CONFIG_DESC, INTERFACE_DESC * 2, acm_function, ENDPOINT_DESC_SIZE * 2 
大小的数据,自动将这些描述符送出去,所以这些描述符必须于这里进行初始化,同时USB Host收到数据后会依描述符格式解析, 
清楚收到的是哪些描述符 

bDeviceClass:指定的为通信设备类用以准确地识别设备 
bInterfaceClass:指定为通信接口类提供一种可以使能各种通信服务的通用机制 
bInterfaceSubClass:指定为通信接口类中的Abstract Control Model(ACM) 
the Data Interface Class: 提供了可以使用bulk和iso传输的机制 

端点分配: 
EP0: Control EP 
EP1: Bulk In, IN EP, USB HOST In, Device Out 
EP2: Bulk OUT, OUT EP, USB Host Out, Device In 

============================ 
11.有关FIFO的一点初步看法(具体的可参考Fifo那两篇) 
GRXFSIZ用法注意:RxFIFO 
1.GRXFSIZ, GNPTXFSIZ:必须写入new value, 
2.不能超过Spec所规定的Max值 
3.以32-bit words为单位 
4.Power-on reset后,默认为0x1800==6144==192KB 
5.Spec有误:P26-5图(b)RXFIZ[31:16]写错了当为RXFIZ[15:0]见P26-35 
Reset Value: 0x0000_1800已dump确认 

Device Mode FIFO Address Mapping: 
1.See P26-5图b 
2.RxFIFO 起始地址fixed to 0 
3.RxFIFO Depth: RX_FIFO_SIZE=512*32bit=2kB 
4.Non-Periodic Tx FIFO start addr: RX_FIFO_SIZE = 512*32bit=2kB See P26-6 
5.Non-Periodic Tx FIFO Depth:NPTX_FIFO_SIZE=512*32bit=2kB 

EP FIFO地址映射: 
1. 布局: 
FIFO地址是布局在所有Registers的最后面,目的是为了适应能动态由用户 
指定FIFO的大小 

2.具体地址: 
1).OTG LINK BASE: 0x7c00_0000 
..... 
最后一个Reg: PCGCCTL地址:0x7c00_0E00 

2).依次类推:0x7C00_1000为EP FIFO始地址 

3). 每个FIFO Size: 4KB布局如下: 2KB有效,2KB闲置 
EP0 FIFO Control EP : 0x7C00_1000 = RxFIFO = RxFIFO的起始地址 
EP1 FIFO Bulk In EP : 0x7C00_2000 
EP2 FIFO Bulk Out EP : 0x7C00_3000 

RxFIFO的起始地址: 0x7C00_1000 
大小 :RXFSIZ[15:0] = 2K=0x200 = (512) words(32-bits) 对应到地址为为:0x1000 

enum EP_FIFO_ADDR { 
control_EP_FIFO = (EP0_FIFO + 0x1000 * CONTROL_EP), //0x7c00_1000 
bulkIn_EP_FIFO = (EP0_FIFO + 0x1000 * BULK_IN_EP), //0x7c00_2000: Host In Device Out -- write: For IN EP 
bulkOut_EP_FIFO = (EP0_FIFO + 0x1000 * BULK_OUT_EP) //0x7c00_3000: Host Out Device In -- read : For OUT EP 
}; 

============================= 
12.速度枚举完成与枚举完成: 
P26-56, P26-53 
注意:这里是速度枚举完成,而非枚举完了 
于DCFG[DevSpd]设置要枚举的速度, 
GINTSTS[ENUMDONE]:表示速度枚举过程完成 
再于DSTS[EnumSpd]查询知USB Device枚举出来的速度 
附:OTGDEV_InitDevice()设置枚举速度为高速 

============================= 
13.有关DAINT与DIEPINTn的关系: 
1.DAINT的中断位清零由清各个DIEPINTn来执行 See P26-58最后一句话 
2.DAINT是个RO Reg 
3.通过清DIEPINT0来清DAINT中的EP0 IN位 

============================= 
14.去掉无关4B Get Status数据的条件: 
第一个条件: 
在收到的数据中前面会有四个80 00 XX XX无关数据 
当用GRXSTSP时,能将前四个无关数据过滤去掉,从而留下后面的 
真正要用的标准设备请求,若此处改成GRXSTSR,也会置位setup 
但就没有了过滤功能,那四个无关数据就老是在RxFIFO中,后面才是标准设备请求 
用GRXSTSP: 
RxFIFO图示:80 00 XX XX 80 06 00 01 00 00 40 00 
变为:80 06 00 01 00 00 40 00 
用GRXSTSR: 
RxFIFO图示:80 00 XX XX 80 06 00 01 00 00 40 00 
依然为:80 00 XX XX 80 06 00 01 00 00 40 00 

第二个条件: 
必须用延时,临界值120ms,不用延时GRXSTSP,GRXSTSR均不行,4B依然残留 

第三个条件: 
紧跟在reset后面,也就是只有第一次有效,后面的均要手工自己对准标准设备描述符的位置 
第一步:收到SETUP包 
第二步:收到DATA0包,并从中解析出标准设备请求 
第三步:ACK回应Host,结束setup stage I 

============================= 
15.完整的USB设备枚举的第一步取设备描述符(default addr:0x0 endp:0x0): 
取设备描述符的Stage 1阶段: 
stage I:收SETUP包并解析: 
USB Host===>USB Device 
sync:0000_0001 setup:0xb4 addr:0x0 endp:0x0 crc5:xx Idle 
sync:0000_0001 DATA0:0xc3 DATA:80 06 00 01 00 00 40 00 crc16:xxxx Idle 
sync:0000_0001 ack:0x4B Idle 

Stage II示意图示:发Device Desc 
Host ==> Device: sync:0000_0001 IN:0x96 addr:0x0 endp:0x0 crc5:X Idle 
当6410检测到IN包后,再发现TxFIFO为空,则NAK回应: 
Device ==> Host: sync:0000_0001 NAK:0x5A Idle 
EOP Idle 
若TxFIFO非空,则将设备描述符发送给Host: 
Device ==> Host: sync:0000_0001 DATA1:0xD2 DATA:设备描述符前8B crc16:XXXX Idle 
Host ==> Device: Sync:0000_0001 ACK:0x4B Idle 
EOP Idle 

Stage III数据图示:State Stage 
Host ==> Device: sync:0000_0001 OUT:0x96 addr:0x0 endp:0x0 crc5 Idle 
Host ==> Device: sync:0000_0001 DATA1:0xD2 DATA:无数据 crc16:0x0000 Idle 
Device ==> Host: sync:0000_0001 ACK:0x4B Idle 

-------------------------------------------------- 
取设备描述符的Stage 2阶段: 
1.当Device 收到Host发来的SETUP包及标准设备请求时,6410 
会自动置位DIEPCTL0:SNAK,以在device处理期间对其余包应答NAK 
于DIEPCTL0:NAKsts中可查看到其改变为1'b1 
所以要置位DIEPCTL0:CNAK以清掉NAK位,以使能应答stage II的IN Token包 
实验结果: 
收SETUP包前:DIEPCTL0:NAKsts=1'b0 :core 发送non-NAK 握手包 base on FIFO status 
收SETUP包后:DIEPCTL0:NAKsts=1'b1 :core 发送NAK 握手包 base on FIFO status 
但是DAINT的EP0 IN位依然置位1,因为DAINT只要端点有事件变化(如收到包)则会置位 
另外IN包必是收到的,只不过6410以NAK自动应答了,所以SNAK管的是6410的应答什么包 
而非禁止收包,所以DAINT仍可用于判断是否收到IN包 

-------------------------------------------------- 
取设备描述符的Stage 3阶段: 
Stage II的数据包示意图示:注意与Stage I相衔接: 
Host ==> Device: sync:0000_0001 IN:0x96 addr:0x0 endp:0x0 crc5:X Idle 
当6410检测到IN包后,再发现TxFIFO为空,则NAK回应: 
Device ==> Host: sync:0000_0001 NAK:0x5A Idle 
EOP Idle 
若TxFIFO非空,则将设备描述符发送给Host: 
Device ==> Host: sync:0000_0001 DATA1:0xD2 DATA:设备描述符前8B crc16:XXXX Idle 
Host ==> Device: Sync:0000_0001 ACK:0x4B Idle 
EOP Idle 

-------------------------------------------------- 
取设备描述符的Stage 3阶段: 
用GRXSTSP[PktSts]检测OUT 包的前提条件: 
1.DOEPCTL0:必须使能,CNAK 
2.RxFIFO必须Flush 

OUT 0LEN DATA1包以结束事务 
6410自动收到OUT Token包及无数据的DATA1包,同时进行自动应答ACK 

Stage III数据图示:注意与Stage I,II相联合: 
Host ==> Device: sync:0000_0001 OUT:0x96 addr:0x0 endp:0x0 crc5 Idle 
Host ==> Device: sync:0000_0001 DATA1:0xD2 DATA:无数据 crc16:0x0000 Idle 
Device ==> Host: sync:0000_0001 ACK:0x4B Idle 

-------------------------------------------- 
取配置描述符: 
Stage I: 发SETUP包,及DATA0:标准设备请求:取设备描述符 
Host==>Device: sync:0000_0001 SETUP:0xB4 addr:X endp:0x0 crc5:X Idle 
Host==>Device: sync:0000_0001 DATA0:0xC3 DATA:80 06 00 02 00 00 09 00 CRC16:XXXX Idle 
Device==>Host: sync:0000_0001 ACK:0x4B Idle 
06:Get Descriptor 02:Configuraion Descriptor 09:配置描述符大小 

Stage II:发IN包以取得配置描述符 
Host==>Device:sync:0000_0001 ADDR:0xX Endp:0x0 crc5:X Idle 
Host==>Device:sync:0000_0001 IN:0x96 DATA1:0xD2 ... ...配置描述符内容 CRC16:XXXX Idle 
Device==>Host:sync:0000_0001 ACK:0x4B Idle 

Stage III:Out 0Len DATA1包以结束事务 
Host==>Device:sync:0000_0001 OUT:0x87 addr:0xX endp:0x0 crc5:X Idle 
Host==>Device: sync:0000_0001 DATA1:0xD2 DATA:无数据 CRC16:0x0000 Idle 
Device==>Host:sync:0000_0001 ACK:0x4B Idle 

补充一点:若是SETUP中指定的要取的字节数很大,大于EP0 MPS,则将会以多个IN包连续传送,如下示意: 
==>setup+DATA0:Get Configuration Descriptor 字节数很大 
==>IN: Part 1 
==>IN: Part 2 
==>IN: Part ... 
==>IN: Part N 
==>OUT 0 Len DATA1 

--------------------------------------------- 
Set Config: 
stage I:(step I ... step III) 
step I: sync:0000_0001 SETUP:0xb4 Addr:0xXX Endp:0x0 crc5:0x15 Idle 
step II: sync:0000_0001 DATA0:0xC3 DATA:00 09 02 00 00 00 00 00(标准设备请求: Set Config) CRC16:0xE4A4 Idle 
step III: sync:0000_0001 ACK:0x4B Idle 

stage II:(step I ... step III) 
step I: sync:0000_0001 IN:0x96 ADDR:0xXX Endp:0x0 CRC5:0x15 Idle 
step II: sync:0000_0001 NAK:0x5A Idle 
EOP Idle 

... ....直到处理完毕setup包 

stage III:(step I ... step III) 
step I: sync:0000_0001 IN:0x96 ADDR:0xXX Endp:0x0 CRC5:0x15 Idle 
step II: sync:0000_0001 DATA1:0xD2 DATA:无数据 CRC16:0x0000 Idle 
step III:sync:0000_0001 ACK:0x4B Idle 

============================= 
16.chk_ep0_in_interrupt()的老的解释:(注意与新的两篇《S3C6410 SETPUP包与DATA0对DAINT的影响调试实验报告.txt》 
S3C6410 OUT包与DATA1对DAINT的影响调试实验报告.txt》相对比,各有一点点出入,但不影响枚举过程,自己再多多试验一把) 

当收到setup包时,由6410自动处理了,置位GRXSTSP,但不会置位EP0 IN 中断位 
当收到紧跟在SETUP包后的DATA0数据包时,6410会解析出数据放入RxFIFO中,这时 
才会置位DAINT EP0 IN中断位,只能用此法来检测DATA0包数据包了,别的方法没有了。 
GRXSTSP中的DPID的DATA0的判定是只用于OUT包而不用于SETUP包 

附:chk_ep0_in_interrupt代码 
void chk_ep0_in_interrupt(void) 

u32 val; 

while(1) { 
val = Inp32(DAINT); 
if(val & 0x1)//EP0 IN产生了中断,说明收到了紧跟在SETUP包后面的DATA0包 
break; 


Outp32(DIEPINT0, Inp32(DIEPINT0)); 


============================= 
17.DIEPCTL0[31]bit 说明: 
是当传输完成了,6410先将此位clear,再去设置中断位,这样才能防止误收发数据。 
看清楚,此位一旦置位 对IN EP则是开始送出数据,所以对IN EP是先准备好数据,再设置此位 
而对OUT EP,此位一旦设置是表示已经分配好内存,可以开始接收,所以对Out EP要先分配好内存, 
作好准备,再设这一位,然后立刻开始接收数据 


============================== 
18.在OUT 0LEN DATA1包以结束事务中,要点是延时: 
msleep(200); 
保证ACK Sent,延时太少,会引起取下一次的设备描述符出错 
在本应取下一次设备描述符时,越过了,直接取了后面的set address导致解析出错 

============================= 
19。有关IN 0Len DATA1包: 
在IN 0Len DATA1包以结束事务时,DIEPINT0:XferCompl会置位 
但实际发现也偶耳置位不上引起不稳定问题,参照OTG 代码,对方 
也没有非得检测此位为1,于是改成超时退出继续运行的方案 

============================= 
20.IN Token 取数据取数据的过程: 
IN Token 取数据,数据直接写入TxFIFO中,不必去检测IN的是否到来,IN包来了后,6410会 
自动检测TxFIFO中是否有数据,有数据的话,6410会自动将数据发出以作为IN包的回应,IN包没到的话 
数据会一直停留在TxFIFO中而不会通过USB线出去,IN包的到来是早已写入TxFIFO中的数据发出的条件 

============================ 
21.windows当响一声叮咚 
第二次取完整配置描述符:0xff:255B:配置描述符+接口描述符*2+端点描述符*2+acm_function 
USB枚举时会取配置描述符,USB Device将会发送大小为CONFIG_DESC_TOTAL_SIZE(0x3e) 
这部份数据就包含了CONFIG_DESC, INTERFACE_DESC * 2, acm_function, ENDPOINT_DESC_SIZE * 2 
大小的数据,将这些描述符送出去 
当执行完此处时,windows当响一声叮咚,表示其已经获得了所有的配置描述符+设备描述符(前面的步奏)并利用其中的VID/PID 
找到了相对于inf中文件中所对应驱动,并已经加载好了,而且于设备管理器中显示出来了 

=================== 
22.USB CDC枚举过程: 
.....一般枚举过程 
Get Line Coding 

set ctrl line state 等待tmc开启 

get line coding 
get line coding 
get line coding 
get line coding 

set line coding 

get line coding 

set ctrl line state 

set line coding 

get line coding 

yuxu9710108  
(member)
09-06-08 16:20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值