<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          s3c2440的USB主機(jī)控制器

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

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

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

          端點(diǎn)描述符(ED)和傳輸描述符(TD)是兩個最基本的通信模塊。ED包含了一個端點(diǎn)的信息,它被HC用來管理使用端點(diǎn)。ED的典型參數(shù)包括端點(diǎn)地址、傳輸速度、最大數(shù)據(jù)包大小,另外ED還提供了TD鏈表的停靠地(錨點(diǎn))。TD是一個依賴于ED的內(nèi)存緩存區(qū),用于與端點(diǎn)之間進(jìn)行數(shù)據(jù)傳輸。當(dāng)HC存取一個ED,并且找到一個有效的TD地址時,則HC就完成了一個簡單的與端點(diǎn)之間的傳輸任務(wù),這個端點(diǎn)是由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)的端點(diǎn)地址;
          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用于中斷、控制和批量端點(diǎn),同步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完成隊(duì)列頭指針,以及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主機(jī)控制器的規(guī)范,因此HC包含了一些片內(nèi)可操作寄存器,這些寄存器同樣可以被HCD所使用。下面我們就簡單介紹OHCI中的寄存器。
          HcRevision:HCI規(guī)范版本;
          HcControl:HC的操作模式,CBSR——在非周期隊(duì)列中,被服務(wù)的控制ED與批量ED之間的比例;CLE——下一幀控制隊(duì)列處理使能;HCFS——USB主機(jī)控制器功能狀態(tài),包括復(fù)位、重新開始、操作和中止;
          HcCommandStatus:HC接收來至HCD的命令,也可反映HC的當(dāng)前狀態(tài),HCR——軟件復(fù)位HC;CLF——確定是否有控制隊(duì)列TD;
          HcInterruptStatus:提供各種能夠觸發(fā)硬件中斷事件的狀態(tài);
          HcInterruptEnable:使能用于控制產(chǎn)生硬件中斷事件的位;
          HcInterruptDisable:無效用于控制產(chǎn)生硬件中斷事件的位
          HcHCCA:HCCA的物理地址;
          HcPeriodCurrentED:當(dāng)前同步或中斷ED的物理地址;
          HcControlHeadED:控制隊(duì)列的第一個ED的物理地址;
          HcControlCurrentED:當(dāng)前控制對立ED的物理地址;
          HcBulkHeadED:批量隊(duì)列的第一個ED的物理地址;
          HcBulkCurrentED:當(dāng)前批量對立ED的物理地址;
          HcDoneHead:被添加在完成隊(duì)列中的最近一個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í)行周期隊(duì)列;
          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é)合本文所介紹的實(shí)際內(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為運(yùn)行狀態(tài)
          rHcControl = 0x80;
          }

          主機(jī)對USB設(shè)備的識別過程稱為設(shè)備枚舉,因此枚舉對于USB至關(guān)重要。在本文,只進(jìn)行下列簡單的5步枚舉過程:
          1、主機(jī)要求得到設(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、主機(jī)用新的地址再次獲取設(shè)備描述符,SETUP包為:0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00,與上次不同,這次得到數(shù)據(jù)長度時實(shí)際的數(shù)據(jù)長度0x12;
          4、主機(jī)讀取設(shè)備全部配置描述符,SETUP包為:0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00,由于主機(jī)不知道設(shè)備描述符的長度,因此這里只要求得到0x40個字節(jié);
          5、主機(jī)發(fā)送SETUP數(shù)據(jù)包:0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00,用以設(shè)置配置,允許所有端點(diǎn)進(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)之間添加主機(jī)要讀取到的數(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)行枚舉之前,主機(jī)一定要確認(rèn)有USB設(shè)備的存在。正確情況下,在確認(rèn)過程中,如果在一段給定時間沒有檢測到設(shè)備,則主機(jī)認(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;

          //第一步,主機(jī)得到設(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;

          //第三步,主機(jī)用新的地址再次獲取設(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;

          //第四步,主機(jī)讀取設(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;


          //第五步,主機(jī)發(fā)送SETUP數(shù)據(jù)包,用以設(shè)置配置,允許所有端點(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,定義的全局變量數(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主機(jī)控制

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();