<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > s3c2440的USB主機控制器

s3c2440的USB主機控制器

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò ) 收藏
s3c2440提供了USB主機接口,它與OHCI v1.0完全兼容。要使用該功能,就必須熟悉OHCI v1.0規范;而要熟悉OHCI v1.0規范,那么還必須先熟悉USB v1.1協(xié)議。因此涉及到該部分的內容較多,要想正確使用s3c2440所提供的USB主機接口也不是一件容易的事情。在這里,我主要介紹USB設備枚舉過(guò)程中所涉及到的一些知識,并給出具體的實(shí)現程序。

OHCI(Open HCI)是目前使用比較廣泛的三種USB主機控制器規范之一。USB體系結構是由四個(gè)主要部分組成:客戶(hù)軟件/USB驅動(dòng),主機控制器驅動(dòng)(HCD),主機控制器(HC)和USB驅動(dòng)。前兩者由軟件實(shí)現,后兩者由硬件實(shí)現。而OHCI就是規范了主機控制器驅動(dòng)和主機控制器之間的接口,以及它們的基本操作。在主機控制器驅動(dòng)和主機控制器之間,有兩個(gè)通信通道,第一個(gè)是應用位于HC的一套可操作寄存器,它們包括控制寄存器、狀態(tài)寄存器和列表指針寄存器;另一個(gè)通道是應用稱(chēng)為主機控制器通信域(HCCA)的共享內存。

USB定義了四種數據傳輸類(lèi)型:控制傳輸、批量傳輸、中斷傳輸和同步傳輸。在OHCI規范中把數據傳輸類(lèi)型分為兩類(lèi):周期傳輸和非周期傳輸。同步傳輸和中斷傳輸屬于周期傳輸,控制傳輸和批量傳輸屬于非周期傳輸。USB定義了每幀的周期為1.0毫秒,為了保證每一幀都能發(fā)生周期傳輸和非周期傳輸,一般地,OHCI把每一幀的帶寬分為四個(gè)部分,首先是發(fā)送SOF,然后是非周期傳輸,緊接著(zhù)是周期傳輸,如果周期傳輸完畢后,還有時(shí)間,則剩余的時(shí)間仍然留給非周期傳輸。

端點(diǎn)描述符(ED)和傳輸描述符(TD)是兩個(gè)最基本的通信模塊。ED包含了一個(gè)端點(diǎn)的信息,它被HC用來(lái)管理使用端點(diǎn)。ED的典型參數包括端點(diǎn)地址、傳輸速度、最大數據包大小,另外ED還提供了TD鏈表的??康兀ㄥ^點(diǎn))。TD是一個(gè)依賴(lài)于ED的內存緩存區,用于與端點(diǎn)之間進(jìn)行數據傳輸。當HC存取一個(gè)ED,并且找到一個(gè)有效的TD地址時(shí),則HC就完成了一個(gè)簡(jiǎn)單的與端點(diǎn)之間的傳輸任務(wù),這個(gè)端點(diǎn)是由ED確定,而所存取的數據內存地址由TD指定。當所有的被TD所定義的數據傳輸完畢后,TD就從ED中解鏈出來(lái),并鏈接到完成列表中。這個(gè)完成列表能夠被HCD所處理,以提供一些完成信息。

ED的數據結構長(cháng)度為16字節,它的數據域有:
FA:USB的功能地址;
EN:USB功能內的端點(diǎn)地址;
D:數據流的傳輸方向,是IN,OUT,還是有TD來(lái)決定傳輸方向;
S:速度,全速還是低速;
K:用于設置跳過(guò)當前ED;
F:鏈接于ED的TD的形式,是通用TD格式還是同步TD格式;
MPS:數據傳輸的最大字節大??;
TailP:TD列表的尾指針;
H:用于停止當前TD列表的處理;
C:數據翻轉進(jìn)位位;
HeadP:TD列表的頭指針;
NextED:下一個(gè)要處理的ED指針。

根據上述說(shuō)明,我們可以定義ED為下面的數據類(lèi)型:
typedef struct _ED {
volatile unsigned int Control;
volatile unsigned int TailP;
volatile unsigned int HeadP;
volatile unsigned int NextEd;
} ED, *P_ED;

由于ED必須是16字節地址對齊形式,因此我們必須用下面的形式來(lái)聲明它的變量:
__align(16) ED ed;

我們可以用下面的函數來(lái)創(chuàng )建一個(gè)ED:
__inline void CreateEd(
unsigned int EDAddr,//ED地址指針
unsigned int MaxPacket,//MPS
unsigned int TDFormat,//F
unsigned int Skip,//K
unsigned int Speed,//S
unsigned int Direction,//D
unsigned int EndPt,//EN
unsigned int FuncAddress,//FA
unsigned int TDQTailPntr,//TailP
unsigned int TDQHeadPntr,//HeadP
unsigned int ToggleCarry,//C
unsigned int NextED)//NextED
{
P_ED pED = (P_ED) EDAddr;
pED->Control = (MaxPacket << 16) | (TDFormat << 15) |(Skip << 14) | (Speed << 13)
| Direction << 11) | (EndPt << 7) | FuncAddress;
pED->TailP = (TDQTailPntr & 0xFFFFFFF0);
pED->HeadP = (TDQHeadPntr & 0xFFFFFFF0) | (ToggleCarry << 1);
pED->NextEd = (NextED & 0xFFFFFFF0);
}

TD共有兩種類(lèi)型:通用TD和同步TD。通用TD用于中斷、控制和批量端點(diǎn),同步TD用于同步傳輸。在這里,我們只給出通用TD的數據結構和定義。

通用TD的數據結構長(cháng)度也是16字節,它的數據域有:
R:緩存湊整,用于設置是否需要最后一個(gè)數據包的長(cháng)度與所定義的長(cháng)度一致;
DP:方向,是IN,OUT,還是SETUP;
DI:延時(shí)中斷;
T:數據翻轉;
EC:傳輸錯誤計數;
CC:條件碼,為上一次企圖傳輸的狀態(tài);
CBP:將要被傳輸的數據內存物理地址;
NextTD:下一個(gè)TD;
BE:將要被傳輸的數據內存物理末字節地址;

根據上述說(shuō)明,我們可以定義通用TD為下面的數據類(lèi)型:
typedef struct _TD {
volatile unsigned int Control;
volatile unsigned int CBP;
volatile unsigned int NextTD;
volatile unsigned int BE;
} TD, *P_TD;

由于通用TD必須是16字節地址對齊形式,因此我們必須用下面的形式來(lái)聲明它的變量:
__align(16) TD td[4];

我們可以用下面的函數來(lái)創(chuàng )建一個(gè)通用TD:
__inline void CreateGenTd(
unsigned int GenTdAddr,//TD地址指針
unsigned int DataToggle,//T
unsigned int DelayInterrupt,//DI
unsigned int Direction,//DP
unsigned int BufRnding,//R
unsigned int CurBufPtr,//CBP
unsigned int NextTD,//NextTD
unsigned int BuffLen)//被傳輸的數據長(cháng)度,由該變量可以得到BE
{
P_TD pTD = (P_TD) GenTdAddr;
pTD->Control = (DataToggle << 24) | (DelayInterrupt << 21)
| (Direction << 19) | (BufRnding << 18);
pTD->CBP = CurBufPtr;
pTD->NextTD = (NextTD & 0xFFFFFFF0);
pTD->BE = (BuffLen) ? CurBufPtr + BuffLen - 1 : CurBufPtr;
}

下面我們給出HCCA的數據結構,它的長(cháng)度為256字節,包括128字節的HCCA中斷表,2字節的HCCA幀數,2字節的HCCA便簽(表示HC是否正在更新HCCA幀數),4字節的HCCA完成隊列頭指針,以及116字節的保留區。根據上述說(shuō)明,我們可以定義HCCA為下面的數據類(lèi)型:
typedef struct _HCCA {
volatile unsigned int HccaInterruptTable[32];
volatile unsigned short HccaFrameNumber;
volatile unsigned short HccaPad1;
volatile unsigned int HccaDoneHead;
volatile unsigned char reserved[116];
} HCCA, *P_HCCA;

由于HCCA必須是256字節地址對齊形式,因此我們必須用下面的形式來(lái)聲明它的變量:
__align(256) HCCA hcca;

OHCI是基于寄存器層描述的USB主機控制器的規范,因此HC包含了一些片內可操作寄存器,這些寄存器同樣可以被HCD所使用。下面我們就簡(jiǎn)單介紹OHCI中的寄存器。
HcRevision:HCI規范版本;
HcControl:HC的操作模式,CBSR——在非周期隊列中,被服務(wù)的控制ED與批量ED之間的比例;CLE——下一幀控制隊列處理使能;HCFS——USB主機控制器功能狀態(tài),包括復位、重新開(kāi)始、操作和中止;
HcCommandStatus:HC接收來(lái)至HCD的命令,也可反映HC的當前狀態(tài),HCR——軟件復位HC;CLF——確定是否有控制隊列TD;
HcInterruptStatus:提供各種能夠觸發(fā)硬件中斷事件的狀態(tài);
HcInterruptEnable:使能用于控制產(chǎn)生硬件中斷事件的位;
HcInterruptDisable:無(wú)效用于控制產(chǎn)生硬件中斷事件的位
HcHCCA:HCCA的物理地址;
HcPeriodCurrentED:當前同步或中斷ED的物理地址;
HcControlHeadED:控制隊列的第一個(gè)ED的物理地址;
HcControlCurrentED:當前控制對立ED的物理地址;
HcBulkHeadED:批量隊列的第一個(gè)ED的物理地址;
HcBulkCurrentED:當前批量對立ED的物理地址;
HcDoneHead:被添加在完成隊列中的最近一個(gè)TD的物理地址;
HcFmInterval:包含一個(gè)14位的FI——用于表示一幀之內所占用的比特時(shí)間,2個(gè)連續的SOFs,和一個(gè)15位PSMPS——用于表示在沒(méi)有引發(fā)調度溢出下可發(fā)送或接收全速最大包大小,FI,PSMPS的推薦值為0x2EDF和0x2778。
HcFmRemaining:14位的倒計數器,以表示當前幀所剩時(shí)間;
HcFmNumber:16位計數器,以提供時(shí)序參考;
HcPeriodicStart:14位可編程數值,以確定HC在什么時(shí)間開(kāi)始執行周期隊列;
HcLSThreshold:11位數值,用于確定是否在EOF之前執行最大8位LS包傳輸;
HcRhDescriptorA:第一個(gè)對跟集線(xiàn)器進(jìn)行描述的寄存器;
HcRhDescriptorB:第二個(gè)對跟集線(xiàn)器進(jìn)行描述的寄存器;
HcRhStatus:包括集線(xiàn)器狀態(tài)域和集線(xiàn)器狀態(tài)更改域;
HcRhPortStstus[1:NDP]:用于控制和報告每個(gè)端口上的事件,在s3c2440中,NDP為2

下面給出OHCI的初始化,它都是基于寄存器的。根據OHCI規范,HCD應該完成下列初始化步驟:
●初始化HCCA數據內存單元
●初始化可操作寄存器,以匹配當前設備數據狀態(tài)
●設置HcHCCA
●設置HcInterruptEnable
●設置HcControl
●設置HcPeriodicStart

結合本文所介紹的實(shí)際內容,OHCI的初始化函數為:
void OHCIInit( )
{
unsigned int fminterval;

//復位
rHcControl = 0;
//寫(xiě)HCCA
rHcHCCA = (volatile unsigned )&hcca;

//設置幀間隔
fminterval = 0x2edf;
rHcFmInterval =((((fminterval - 210) * 6) / 7) << 16)| fminterval;
rHcPeriodicStart= (fminterval * 9) / 10;

//初始化HcDoneHead
rHcDoneHead = 0x00;
hcca.HccaDoneHead = 0x0000;

//設置HC為運行狀態(tài)
rHcControl = 0x80;
}

主機對USB設備的識別過(guò)程稱(chēng)為設備枚舉,因此枚舉對于USB至關(guān)重要。在本文,只進(jìn)行下列簡(jiǎn)單的5步枚舉過(guò)程:
1、主機要求得到設備描述符,SETUP數據包為:0x80, 0x06,0x00,0x01,0x00,0x00,0x40,0x00,得到的數據長(cháng)度最大為0x40;
2、第二個(gè)SETUP包是為設備分配一個(gè)地址,內容一般為:0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00。其中的02表示為設備分配的地址為0x02,以后我們再對該設備操作時(shí),就只能使用0x02這個(gè)地址值;
3、主機用新的地址再次獲取設備描述符,SETUP包為:0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00,與上次不同,這次得到數據長(cháng)度時(shí)實(shí)際的數據長(cháng)度0x12;
4、主機讀取設備全部配置描述符,SETUP包為:0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00,由于主機不知道設備描述符的長(cháng)度,因此這里只要求得到0x40個(gè)字節;
5、主機發(fā)送SETUP數據包:0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00,用以設置配置,允許所有端點(diǎn)進(jìn)入工作狀態(tài)。
對USB設備枚舉我們只做了簡(jiǎn)單的介紹,關(guān)于枚舉的其他步驟以及SETUP數據包各個(gè)字節的具體含義,請閱讀USB協(xié)議的第9章。

下面我們就主要介紹OHCI規范是如何完成USB設備枚舉的。前面我們已經(jīng)介紹過(guò)了,OHCI數據傳輸主要依靠ED和TD,其中TD是掛靠在ED上的。ED主要用來(lái)設置傳輸的各種參數,TD則主要負責具體的數據傳輸。根據USB協(xié)議,USB的設備枚舉只涉及控制傳輸??刂苽鬏斪钌儆袃蓚€(gè)事務(wù)階段:建立和狀態(tài),控制傳輸可以有選擇性地包括建立和狀態(tài)階段之間的數據階段。在這里,控制寫(xiě)傳輸不需要數據階段,而控制讀需要在建立和狀態(tài)之間添加主機要讀取到的數據。一般來(lái)說(shuō),完成一次控制寫(xiě)傳輸需要3個(gè)TD:第一個(gè)發(fā)送Setup包,第二個(gè)用于接收握手或零長(cháng)度的數據包,第三個(gè)用于發(fā)送狀態(tài);而完成一次控制讀傳輸需要4個(gè)TD:第一個(gè)發(fā)送Setup包,第二個(gè)用于接收數據,第三個(gè)用于發(fā)送一個(gè)零長(cháng)度的數據包,,第四個(gè)用于接收狀態(tài)。

下面給出具體的USB設備枚舉的函數。在進(jìn)行枚舉之前,主機一定要確認有USB設備的存在。正確情況下,在確認過(guò)程中,如果在一段給定時(shí)間沒(méi)有檢測到設備,則主機認為沒(méi)有USB設備。“一段給定的時(shí)間”應該由定時(shí)器來(lái)完成。在這里,為了簡(jiǎn)化程序,我們只用計數來(lái)代替定時(shí)。
int USB_Enum()
{
int i;
//判斷有無(wú)USB設備
for(i=0;i<100000;i++)
{
if (rHcRhPortStatus1 & 0x01)
{
rHcRhPortStatus1 = (1 << 4);//端口復位
while (rHcRhPortStatus1 & (1 << 4))
;//等待復位結束
rHcRhPortStatus1 = (1 << 1);//使能該端口
break;
}
else if (rHcRhPortStatus2 & 0x01)
{
rHcRhPortStatus2 = (1 << 4);//端口復位
while (rHcRhPortStatus2 & (1 << 4))
;//等待復位結束
rHcRhPortStatus2 = (1 << 1);//使能該端口
break;
}
}

if (i>90000)
return 0x44;

//第一步,主機得到設備描述符
CreateEd(
(unsigned int) &ed,// ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0x0,// Endpoint
0x0,// Func Address,初始為0
(unsigned int) &td[3],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

//建立PID
CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
0x2,// DelayInterrupt
0x0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup1,// Current Buffer Pointer,定義的全局變量數組
//const char pSetup1[8] ={0x80,0x06,0x00,0x01,0x00,0x00,0x40,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

//接收數據
CreateGenTd(
(unsigned int) &td[1],// TD Address
0,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
(unsigned int) pData1,// Current Buffer Pointer,定義的全局變量數組
// char pData1[0x40];通過(guò)讀取該數組,可以獲知設備描述符
(unsigned int) &td[2],// Next TD
0x40);// Buffer Length

//零長(cháng)度數據包
CreateGenTd(
(unsigned int) &td[2],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x1,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) &td[3],// Next TD
0x0);// Buffer Length

//接收狀態(tài)
CreateGenTd(
(unsigned int) &td[3],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) 0,// Next TD
0x0);// Buffer Length

//設置寄存器
rHcControlHeadED = (unsigned int )& ed;
rHcControlCurrentED = (unsigned int )& ed;

//控制列表處理使能,開(kāi)始工作
rHcControl = 0x90;

//通知HC控制列表已填充
rHcCommandStatus = 0x02;


//第二步為設備分配地址
CreateEd(
(unsigned int) &ed,// ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0,// Endpoint
0,// Func Address
(unsigned int) &td[2],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

//建立PID
CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
2,// DelayInterrupt
0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup2,// Current Buffer Pointer,定義的全局變量數組
//const char pSetup2[8] ={0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

//接收零長(cháng)度數據包
CreateGenTd(
(unsigned int) &td[1],// TD Address
0,// Data Toggle
2,// DelayInterrupt
2,// Direction
1,// Buffer Rounding
(unsigned int) 0,// Current Buffer Pointer
(unsigned int) &td[2],// Next TD
0);// Buffer Length

//發(fā)送狀態(tài)
CreateGenTd(
(unsigned int) &td[2],// TD Address
3,// Data Toggle
2,// DelayInterrupt
1,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) 0,// Next TD
0x0);// Buffer Length

rHcControlHeadED = (unsigned int )& ed;
rHcControlCurrentED = (unsigned int )& ed;
rHcControl = 0x90;
rHcCommandStatus = 0x02;

//第三步,主機用新的地址再次獲取設備描述符
CreateEd(
(unsigned int) &ed, // ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0x0,// Endpoint
0x2,// Func Address,新的地址
(unsigned int) &td[3],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
0x2,// DelayInterrupt
0x0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup3,// Current Buffer Pointer,定義的全局變量數組
//const char pSetup3[8] ={0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

CreateGenTd(
(unsigned int) &td[1],// TD Address
0,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
(unsigned int) pData3,// Current Buffer Pointer,定義的全局變量數組
// char pData3[0x12];通過(guò)讀取該數組,可以獲知設備描述符
(unsigned int) &td[2],// Next TD
0x12);// Buffer Length

CreateGenTd(
(unsigned int) &td[2],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x1,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) &td[3],// Next TD
0x0);// Buffer Length

CreateGenTd(
(unsigned int) &td[3],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) 0,// Next TD
0x0);// Buffer Length

rHcControlHeadED = (unsigned int )& ed;
rHcControlCurrentED = (unsigned int )& ed;
rHcControl = 0x90;
rHcCommandStatus = 0x02;

//第四步,主機讀取設備全部配置描述符
CreateEd(
(unsigned int) &ed, // ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0x0,// Endpoint
0x2,// Func Address
(unsigned int) &td[3],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
0x2,// DelayInterrupt
0x0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup4,// Current Buffer Pointer,定義的全局變量數組
//const char pSetup4[8] ={0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length


CreateGenTd(
(unsigned int) &td[1],// TD Address
0,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
(unsigned int) pData4,// Current Buffer Pointer,定義的全局變量數組
// char pData4[0x40];通過(guò)讀取該數組,可以獲知配置描述符
(unsigned int) &td[2],// Next TD
0x40);// Buffer Length

CreateGenTd(
(unsigned int) &td[2],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x1,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) &td[3],// Next TD
0x0);// Buffer Length

CreateGenTd(
(unsigned int) &td[3],// TD Address
3,// Data Toggle
0x2,// DelayInterrupt
0x2,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) 0,// Next TD
0x0);// Buffer Length

rHcControlHeadED = (unsigned int )& ed;
rHcControlCurrentED = (unsigned int )& ed;
rHcControl = 0x90;
rHcCommandStatus = 0x02;


//第五步,主機發(fā)送SETUP數據包,用以設置配置,允許所有端點(diǎn)進(jìn)入工作狀態(tài)。
CreateEd(
(unsigned int) &ed, // ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0,// Endpoint
2,// Func Address
(unsigned int) &td[2],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
2,// DelayInterrupt
0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup5,// Current Buffer Pointer,定義的全局變量數組
//const char pSetup5[8] ={0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

CreateGenTd(
(unsigned int) &td[1],// TD Address
0,// Data Toggle
2,// DelayInterrupt
2,// Direction
1,// Buffer Rounding
(unsigned int) 0,// Current Buffer Pointer
(unsigned int) &td[2],// Next TD
0);// Buffer Length

CreateGenTd(
(unsigned int) &td[2],// TD Address
3,// Data Toggle
2,// DelayInterrupt
1,// Direction
1,// Buffer Rounding
0x0,// Current Buffer Pointer
(unsigned int) 0,// Next TD
0x0);// Buffer Length

rHcControlHeadED = (unsigned int )& ed;
rHcControlCurrentED = (unsigned int )& ed;
rHcControl = 0x90;
rHcCommandStatus = 0x02;

return 0x88;
}


關(guān)鍵詞: s3c2440USB主機控制

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>