新聞中心

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

s3c2440的USB主機控制器

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

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

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

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

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

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

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

我們可以用下面的函數(shù)來創(chuàng)建一個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共有兩種類型:通用TD和同步TD。通用TD用于中斷、控制和批量端點,同步TD用于同步傳輸。在這里,我們只給出通用TD的數(shù)據(jù)結(jié)構(gòu)和定義。

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

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

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

我們可以用下面的函數(shù)來創(chuàng)建一個通用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)//被傳輸?shù)臄?shù)據(jù)長度,由該變量可以得到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的數(shù)據(jù)結(jié)構(gòu),它的長度為256字節(jié),包括128字節(jié)的HCCA中斷表,2字節(jié)的HCCA幀數(shù),2字節(jié)的HCCA便簽(表示HC是否正在更新HCCA幀數(shù)),4字節(jié)的HCCA完成隊列頭指針,以及116字節(jié)的保留區(qū)。根據(jù)上述說明,我們可以定義HCCA為下面的數(shù)據(jù)類型:
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字節(jié)地址對齊形式,因此我們必須用下面的形式來聲明它的變量:
__align(256) HCCA hcca;

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

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

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

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

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

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

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

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

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

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

if (i>90000)
return 0x44;

//第一步,主機得到設(shè)備描述符
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,定義的全局變量數(shù)組
//const char pSetup1[8] ={0x80,0x06,0x00,0x01,0x00,0x00,0x40,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

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

//零長度數(shù)據(jù)包
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

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

//控制列表處理使能,開始工作
rHcControl = 0x90;

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


//第二步為設(shè)備分配地址
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,定義的全局變量數(shù)組
//const char pSetup2[8] ={0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00};
(unsigned int) &td[1],// Next TD
8);// Buffer Length

//接收零長度數(shù)據(jù)包
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;

//第三步,主機用新的地址再次獲取設(shè)備描述符
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,定義的全局變量數(shù)組
//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,定義的全局變量數(shù)組
// char pData3[0x12];通過讀取該數(shù)組,可以獲知設(shè)備描述符
(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;

//第四步,主機讀取設(shè)備全部配置描述符
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,定義的全局變量數(shù)組
//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,定義的全局變量數(shù)組
// char pData4[0x40];通過讀取該數(shù)組,可以獲知配置描述符
(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數(shù)據(jù)包,用以設(shè)置配置,允許所有端點進(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,定義的全局變量數(shù)組
//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ù)專區(qū)

關(guān)閉