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