USB概述及S3C2440 USB DEVICE
USB概述 USB主要用于中速和低速的外設(shè)。USB通過PCI總線和PC機(jī)的內(nèi)部系統(tǒng)數(shù)據(jù)線連接,,實(shí)現(xiàn)數(shù)據(jù)的傳送,。USB的網(wǎng)絡(luò)協(xié)議中規(guī)定每個USB的系統(tǒng)有且僅有一個HOST。 USB2.0協(xié)議的理論速度是480Mb/s ,,現(xiàn)在的USB3.0協(xié)議理論速度能達(dá)到4Gb/s,。 主要特點(diǎn): 支持即插即用,,傳輸速度快,連接方便,,獨(dú)立供電,,低成本;USB 使用一個4針插頭作為標(biāo)準(zhǔn)插頭,,通過這個標(biāo)準(zhǔn)插頭,,采用菊花鏈形式可以把多達(dá)127個的 USB 外設(shè)連接起來,所有的外設(shè)通過協(xié)議來共享 USB 的帶寬,。 組成: USB 規(guī)范中將 USB 分為五個部分:控制器,、控制器驅(qū)動程序、USB芯片驅(qū)動程序,、USB 設(shè)備以及針對不同USB 設(shè)備的客戶驅(qū)動程序。 控制器(Host Controller),,主要負(fù)責(zé)執(zhí)行由控制器驅(qū)動程序發(fā)出的命令,,如位于 PC 主板的USB 控制芯片。 控制器驅(qū)動程序(Host Controller Driver),,在控制器與USB 設(shè)備之間建立通信信道,,一般由操作系統(tǒng)或控制器廠商提供。 USB芯片驅(qū)動程序(USB Driver),,提供對USB芯片的支持,,設(shè)備上的固件。 USB設(shè)備(USB Device),,包括與 PC 相連的USB 外圍設(shè)備,。 設(shè)備驅(qū)動程序(Client Driver Software),驅(qū)動USB 設(shè)備的程序,,一般由USB 設(shè)備制造商提供,。 傳輸方式: 每次傳輸會分解成若干個數(shù)據(jù)包在USB總線上傳輸。每次傳輸必須經(jīng)歷兩個或三個部分,,第一部分是USB控制器向USB設(shè)備發(fā)出命令,,第二部分是USB控制器和USB設(shè)備之間傳遞讀寫請求,其方向主要看第一部分的命令式讀還是寫,,第二部分有時可以沒有,。第三部分是握手信號。 1.控制傳輸方式:負(fù)責(zé)向USB設(shè)置一些控制信息,,傳送這種事務(wù)的管道是控制管道,。在每個USB設(shè)備中都會有控制管道,也就是說控制管道在USB設(shè)備中是必須的,??刂苽鬏斠卜譃槿齻€階段,,令牌階段、數(shù)據(jù)傳送階段,、握手階段,。 2.同步傳輸方式:該方式用來聯(lián)接需要連續(xù)傳輸數(shù)據(jù),且對數(shù)據(jù)的正確性要求不高而對時間極為敏感的外部設(shè)備,,如麥克風(fēng),、嗽叭以及電話等。同步傳輸方式以固定的傳輸速率,,連續(xù)不斷地在主機(jī)與 USB 設(shè)備之間傳輸數(shù)據(jù),,在傳送數(shù)據(jù)發(fā)生錯誤時,USB 并不處理這些錯誤,,而是繼續(xù)傳送新的數(shù)據(jù),。同步傳輸方式的發(fā)送方和接收方都必須保證傳輸速率的匹配,不然會造成數(shù)據(jù)的丟失,。 同步傳輸事務(wù)只有兩個階段,,令牌階段、數(shù)據(jù)階段,,因?yàn)椴魂P(guān)心數(shù)據(jù)的正確性,,故沒有握手階段。 3.中斷傳輸 (Interrupt):該方式用來傳送數(shù)據(jù)量較小,, 但需要及時處理,, 以達(dá)到實(shí)時效果的設(shè)備, 此方式主要用在偶然需要少量數(shù)據(jù)通信,,但服務(wù)時間受限制的鍵盤,、鼠標(biāo)以及操縱桿等設(shè)備上。 也分上述三個階段,。 4.批量傳輸方式:主要是大塊的數(shù)據(jù),,傳輸這種事務(wù)的管道叫做Bulk管道。這種事務(wù)傳輸?shù)臅r候分為三個部分:第一部分是HOST端發(fā)出一個BULK的令牌請求,,如果令牌是IN請求則是從Device到Host端的請求,,如果是OUT令牌,則是從HOST到DEVICE端的請求,。第二部分是傳輸數(shù)據(jù)的階段,,根據(jù)先前請求的令牌的類型,數(shù)據(jù)傳輸有可能是IN方向和OUT方向,。傳輸數(shù)據(jù)的時候用DATA0和DATA1令牌攜帶著數(shù)據(jù)交替?zhèn)魉?。第三部分是握手信號。如果是IN方向,,數(shù)據(jù)信號應(yīng)該是HOST端發(fā)出,,如果是OUT方向,,握手信號應(yīng)該是DEVICE端發(fā)出。握手信號可以是ACK,,表示正常響應(yīng),,也可以是NAK表示沒有正確傳送。STALL表示出現(xiàn)主機(jī)出現(xiàn)不可預(yù)知的錯誤,。在第二部分,,數(shù)據(jù)傳送由DATA0和DATA1數(shù)據(jù)包交替?zhèn)魉汀?shù)據(jù)傳輸格式DATA1和DATA0,,兩個是重復(fù)數(shù)據(jù),,確保在1數(shù)據(jù)丟失時0可以補(bǔ)上,不止數(shù)據(jù)丟失,。 USB描述符: USB設(shè)備通過描述符來反映他們的屬性,。描述符是有定義好的格式的數(shù)據(jù)結(jié)構(gòu),每個描述符以一個字節(jié)打頭表明本描述符的長度,,緊跟其后是一個字節(jié)的描述符類信息,。 一個USB設(shè)備有一個設(shè)備描述符,設(shè)備描述符里面決定了該設(shè)備有多少種配置,,每種配置描述符對應(yīng)著配置描述符;而在配置描述符中又定義了該配置里面有多少個接口,,每個接口有對應(yīng)的接口描述符,;在接口描述符里面又定義了該接口有多少個端點(diǎn),每個端點(diǎn)對應(yīng)一個端點(diǎn)描述符,;端點(diǎn)描述符定義了端點(diǎn)的大小,,類型等等。由此我們可以看出,,USB的描述符之間的關(guān)系是一層一層的,,最上一層是設(shè)備描述符,下面是配置描述符,,再下面是接口描述符,,再下面是端點(diǎn)描述符。在獲取描述符時,,先獲取設(shè)備描述符,,然后再獲取配置描述符,根據(jù)配置描述符中的配置集合長度,,一次將配置描述符,、接口描述符、端點(diǎn)描述符一起一次讀回,。其中可能還會有獲取設(shè)備序列號,,廠商字符串,,產(chǎn)品字符串等。 以下詳細(xì)介紹USB描述符: //設(shè)備描述符 struct USB_Dev_descriptor { U8 blength; //設(shè)備描述符的字節(jié)數(shù)大小 U8 bDescriptorType; //設(shè)備描述符類型編號 U16 bcdUSB; //USB版本號 U8 bDeviceClass; //USB分配的設(shè)備類代碼 U8 bDeviceSubClass; //USB分配的子類代碼 U8 bDeviceProtocol; //USB分配的設(shè)備協(xié)議代碼 U8 bMaxPacketSize0; //端點(diǎn)0的最大包大小 U16 idVendor; //廠商編號 U16 idProduct; //產(chǎn)品編號 U16 bcdDevice; //設(shè)備出廠編號 U8 iManufacturer; //設(shè)備廠商字符串的索引 U8 iProduct; //描述產(chǎn)品字符串的索引 U8 iSerialNumber; //描述設(shè)備序列號字符串的索引 U8 bNumConfigurations; //可能的配置數(shù)量 }descDev; //配置描述符 struct USB_Con_descriptor { U8 bLength; //配置描述符的字節(jié)數(shù)大小 U8 bDescriptorType; //配置描述符類型編號 U8 wTotalLength; //此配置返回的所有數(shù)據(jù)大小 U8 bNumInterfaces; //此配置所支持的接口數(shù)量 U8 bConfigurationValue; //Set_Configuration命令所需要的參數(shù)值 U8 iConfiguration; //描述該配置的字符串的索引值 U8 bmAttributes; //供電模式的選擇 U8 MaxPower; //設(shè)備從總線提取的最大電流 }descCon; //接口描述符 struct USB_Inf_descriptor { U8 bLength; //接口描述符的字節(jié)數(shù)大小 U8 bDescriptorType; //接口描述符的類型編號 U8 bInterfaceNumber; //該接口的編號 U8 bAlternateSetting; //備用的接口描述符編號 U8 bNumEndpoints; //該接口使用的端點(diǎn)數(shù),,不包括端點(diǎn)0 U8 bInterfaceClass; //接口類型 U8 bInterfaceSubClass; //接口子類型 U8 bInterfaceProtocol; //接口遵循的協(xié)議 U8 iInterface; //描述該接口的字符串索引值 }descInf; //端口描述符 struct USB_Epn_descriptor { U8 bLength; //端點(diǎn)描述符字節(jié)數(shù)大小 U8 bDescriptorType; //端點(diǎn)描述符類型編號 U8 bEndpointAddress; //端點(diǎn)地址及輸入輸出屬性 U8 bmAttributes; //端點(diǎn)的傳輸類型屬性 U16 wMaxPacketSize; //端點(diǎn)收,、發(fā)的最大包大小 U8 bInterval; //主機(jī)查詢端點(diǎn)的時間間隔 }descEp0,descEp1; 描述符配置實(shí)例: void USB_descriptor() { //設(shè)備描述符 descDev.blength=0x12; //設(shè)備描述符的字節(jié)數(shù)大小,這里是18字節(jié) descDev.bDescriptorType=1; //設(shè)備描述符類型編號,,設(shè)備描述符是01 descDev.bcdUSB=0x0110; //USB版本號,,這里是USB01.10,即USB1.1,。 descDev.bDeviceClass=0xFF; descDev.bDeviceSubClass=0; descDev.bDeviceProtocol=0; descDev.bMaxPacketSize0=8; //端點(diǎn)0的最大包大小,,這里為8字節(jié) descDev.idVendor=0x5345; descDev.idProduct=0x1234; descDev.bcdDevice=0x100; descDev.iManufacturer=1; descDev.iProduct=2; descDev.iSerialNumber=0; descDev.bNumConfigurations=1; //配置描述符 descCon.bLength=9; //配置描述符的字節(jié)數(shù)大小 descCon.bDescriptorType=2; //配置描述符類型編號 descCon.wTotalLength=0x20; //配置描述符集合的總大小 descCon.bNumInterfaces=1; //只包含一個接口 descCon.bConfigurationValue=1; //該配置的編號 descCon.iConfiguration=0; //iConfiguration字段 descCon.bmAttributes=0x80; //采用總線供電,不支持遠(yuǎn)程喚醒 descCon.MaxPower=25; //從總線獲取最大電流50mA //接口描述符 descInf.bLength=9; //接口描述符的字節(jié)數(shù)大小,,這里為9 descInf.bDescriptorType=4; //接口數(shù)4 descInf.bInterfaceNumber=0; //接口編號為4 descInf.bAlternateSetting=0; //該接口描述符的編號為0 descInf.bNumEndpoints=2; //非0端點(diǎn)數(shù)量為2,,只使用端點(diǎn)主端點(diǎn)輸入和輸出 descInf.bInterfaceClass=0xff; descInf.bInterfaceSubClass=0; descInf.bInterfaceProtocol=0; descInf.iInterface=0; //接口描述符字符串索引,為0,,表示沒有字符串 //端口描述符 descEp0.bLength=7; //端點(diǎn)描述符的字節(jié)數(shù)大小,,這里為7 descEp0.bDescriptorType=5; //端點(diǎn)描述符類型編號,端點(diǎn)描述符為5 descEp0.bEndpointAddress=0x81; //端點(diǎn)號,,主輸入端點(diǎn) descEp0.bmAttributes=2; //使用的傳輸類型,,批量傳輸 descEp0.wMaxPacketSize=32; //該端點(diǎn)支持的最大包尺寸,64字節(jié) descEp0.bInterval=0; //中斷掃描時間,,對批量傳輸無效 descEp1.bLength=7; descEp1.bDescriptorType=5; descEp1.bEndpointAddress=3; descEp1.bmAttributes=2; descEp1.wMaxPacketSize=32; descEp1.bInterval=0; } USB設(shè)備枚舉過程: 1. 主機(jī)檢測到設(shè)備插上,,總線復(fù)位:當(dāng)設(shè)備與主機(jī)連接時,主機(jī)將檢測到連接條件,。當(dāng)USB線的D+數(shù)據(jù)線拉至Vse以上2.5us時,,主機(jī)就開始進(jìn)行總線復(fù)位。 2. 主機(jī)讀取設(shè)備描述符(第一次):主機(jī)連接時使用默認(rèn)地址(0)讀取設(shè)備描述符,。S3C2440的端點(diǎn)0的緩沖區(qū)是16個字節(jié),,程序中設(shè)置為8個字節(jié),故S3C2440作為設(shè)備先發(fā)送8個字節(jié)的設(shè)備描述符,。當(dāng)主機(jī)接收到這8個字節(jié)后,,就認(rèn)為有設(shè)備連接,即發(fā)送一個0字節(jié)的數(shù)據(jù)包到設(shè)備作為應(yīng)答,。 3. 分配地址:主機(jī)給設(shè)備分配一個地址,。默認(rèn)分配地址為0x02,在以后通信中,,設(shè)備只對0x02地址的信息應(yīng)答,。 4. 主機(jī)從新地址獲取設(shè)備描述符:程序中接收數(shù)據(jù)包設(shè)置成8字節(jié),18字節(jié)的設(shè)備描述符要分3次發(fā)送,。最后主機(jī)發(fā)送一個0字節(jié)的數(shù)據(jù)包到設(shè)備作為應(yīng)答,。 5. 主機(jī)獲取配置描述符,。 6. 主機(jī)讀取描述符集合:主機(jī)除了讀取設(shè)備描述符和配置描述符之外,還讀取接口描述符,。在這里主機(jī)使用再次讀取配置的方法來讀取配置描述符,、接口描述符和端點(diǎn)描述符的集合。這里請求的字節(jié)數(shù)為0xFF,。 7. 設(shè)置配置:主機(jī)讀取完描述符后,,需要對設(shè)備進(jìn)行配置,使設(shè)備從地址狀態(tài)進(jìn)入配置狀態(tài),。 8. 讀取配置狀態(tài)(可選):主機(jī)設(shè)置完配置后,,設(shè)備即可使用。主機(jī)有時會對設(shè)備的狀態(tài)進(jìn)行讀取,。 9. 讀取接口狀態(tài)(可選),。 S3C2440 USB DEVICE S3C2440 USB DEVICE簡介: USB設(shè)備控制器采用DMA接口方案,提供全速高性能的控制器,,允許控制傳輸,、中斷傳輸和DMA接口的批量傳輸。它兼容USB1.1,具有5個帶FIFO的端點(diǎn):端點(diǎn)0(EP0,,16字節(jié),,雙向控制端點(diǎn))、端點(diǎn)1,,2,3,4(128字節(jié),,中斷或DMA,批量端點(diǎn)),。 USB初始化: 1. UCLK初始化:USB主機(jī)和USB設(shè)備接口都需要48MHz的時鐘。在S3C2440中,,這個時鐘是由UPLL(USB專用)提供,,所以操作前要對UPLLCON寄存器進(jìn)行設(shè)置。由于CLKDIVN(DIVN_UPLL)和CLKSLOW(UCLK_ON)兩個寄存器中有關(guān)UCLK的位的初始值均為0,,故只要設(shè)置UPLLCON=0x38022,。 2. 初始化描述符,見描述符配置實(shí)例,。 3. 重新配置USB設(shè)備:主要配置各端點(diǎn)的最大包字節(jié)數(shù),,傳輸模式,IN/OUT(數(shù)據(jù)方向)和使能需要的中斷,。 需要設(shè)置的寄存器有:電源管理寄存器PWR_REG,、索引寄存器INDEX_REG(對各端點(diǎn)進(jìn)行設(shè)置前要使索引寄存器指向該端點(diǎn),如設(shè)置端點(diǎn)0,,INDEX_REG=0,。),、最大包寄存器MAXP_REG、端點(diǎn)0控制狀態(tài)寄存器EP0_CSR,、端點(diǎn)輸入控制狀態(tài)寄存器IN_CSR1_REG,、端點(diǎn)輸入控制狀態(tài)寄存器2(IN_CSR2_REG)、端點(diǎn)輸出控制狀態(tài)寄存器OUT_CSR1_REG,、端點(diǎn)輸出控制狀態(tài)寄存器2(OUT_CSR2_REG),、端點(diǎn)中斷寄存器EP_INT_REG、USB中斷寄存器USB_INT_REG,、端點(diǎn)中斷使能寄存器EP_INT_EN_REG,、USB中斷使能寄存器USB_INT_EN_REG。 各寄存器的具體設(shè)置請參考有關(guān)手冊(可參考GEC2440實(shí)戰(zhàn)手冊或芯片手冊),。 實(shí)例: void USB_reset() { rPWR_REG=0; //禁止睡眠模式 rINDEX_REG=0; //對EP0有關(guān)的寄存器進(jìn)行操作 rMAXP_REG=1; //EP0最大包8字節(jié) rEP0_CSR=0xC0; rINDEX_REG=1; //對EP1有關(guān)的寄存器進(jìn)行操作 rMAXP_REG=4; //EP1最大包32字節(jié) rIN_CSR1_REG=(1<<6)|(1<<3); //沖掉FIFO中的數(shù)據(jù),,數(shù)據(jù)包中的PID保持DATA0 rIN_CSR2_REG=(1<<5)|(1<<4)|(0<<6); //IN模式,禁止DMA中斷,批量傳輸模式 rOUT_CSR1_REG=0x80; //數(shù)據(jù)切換序列位復(fù)位到DATA0 rOUT_CSR2_REG=(0<<6)|(1<<5); //端點(diǎn)配置成批量傳輸模式,,禁止中斷 rINDEX_REG=2; rMAXP_REG=8; //EP2最大包64字節(jié) rIN_CSR1_REG=(1<<6)|(1<<3); rIN_CSR2_REG=(1<<5)|(1<<4); rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); rINDEX_REG=3; rMAXP_REG=4; //EP3最大包32字節(jié) rIN_CSR1_REG=(1<<6)|(1<<3); //沖掉FIFO中的數(shù)據(jù),,數(shù)據(jù)包中的PID保持DATA0 rIN_CSR2_REG=(0<<5)|(1<<4); //OUT模式,禁止DMA中斷 rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); //端點(diǎn)配置成BULK模式,禁止中斷 rINDEX_REG=4; rMAXP_REG=8; //EP4最大包64字節(jié) rIN_CSR1_REG=(1<<6)|(1<<3); rIN_CSR2_REG=(0<<5)|(1<<4); //OUT模式,禁止DMA中斷 rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); //端點(diǎn)配置成批量傳輸模式,,禁止中斷 rEP_INT_REG=(1<<3)|(1<<2)|(1<<1)|(1<<0); //清除所有端點(diǎn)的中斷 rUSB_INT_REG=(1<<2)|(1<<1)|(1<<0); //清零USB中斷寄存器rEP_INT_EN_REG=(1<<3)|(1<<1)|(1<<0)/*0xD*/;//使能EP0,,EP1,EP3中斷 rUSB_INT_EN_REG=4; //使能復(fù)位中斷
} 4. 中斷初始化:中斷時指向中斷服務(wù)程序,。 數(shù)據(jù)傳輸: 一般采用中斷傳輸模式,,故進(jìn)入中斷后先判斷中斷類型,再具體執(zhí)行中斷類型的服務(wù)程序,。如下程序: void __irq USB_INT() { U8 usb_Int, Ep_Int; U8 Index=rINDEX_REG; //保存索引寄存器值(現(xiàn)場保護(hù)) usb_Int=rUSB_INT_REG; //保存中斷標(biāo)志寄存器 Ep_Int=rEP_INT_REG; if(usb_Int&1) //總線上超過3ms沒有活動信號引起中斷 { rUSB_INT_REG=1; //清除中斷標(biāo)志位 } if(usb_Int&2) rUSB_INT_REG=2; //恢復(fù)引起的中斷 if(usb_Int&4) //接收到復(fù)位信號引起的中斷 { USB_reset(); //重新配置USB設(shè)備 rUSB_INT_REG=4; //復(fù)位USB后清除復(fù)位中斷 PrepareEp1Fifo(); //準(zhǔn)備發(fā)送數(shù)據(jù) } if(Ep_Int&1) //端點(diǎn)0中斷 { rEP_INT_REG=1; Ep0Handler(); //進(jìn)入控制傳輸中斷處理程序 } if(Ep_Int&2) { rEP_INT_REG=2; Ep1Handler(); //進(jìn)入Ep1中斷處理程序(BULK IN) } if(Ep_Int&4) rEP_INT_REG=4; if(Ep_Int&8) { rEP_INT_REG=8; Ep3Handler(); //進(jìn)入Ep3中斷處理程序(BULK OUT) } if(Ep_Int&0x10) rEP_INT_REG=0x10; ClearPending(BIT_USBD); //USB設(shè)備中斷處理完畢,,清除中斷標(biāo)志位 rINDEX_REG=Index; //恢復(fù)索引寄存器原來的值(恢復(fù)現(xiàn)場) } 其中控制傳輸中斷服務(wù)程序(Ep0Handler())處理主機(jī)向USB設(shè)備發(fā)出命令的中斷。在此程序中,,要分別對接收命令過程中出現(xiàn)的有效命令(即令牌包)寫入(包括對命令內(nèi)容的處理),、命令寫入出錯引起的停止、命令傳輸結(jié)束進(jìn)行處理,。Ep1/3中斷處理程序處理數(shù)據(jù)的發(fā)送和接收,,在數(shù)據(jù)發(fā)送和接收結(jié)束之后清除標(biāo)志位。具體程序見實(shí)戰(zhàn)手冊(可參考GEC2440實(shí)戰(zhàn)手冊或2410_MDK實(shí)驗(yàn)教程),。 |
|