基于STM32的USB程序開發(fā)筆記_第1頁
基于STM32的USB程序開發(fā)筆記_第2頁
基于STM32的USB程序開發(fā)筆記_第3頁
基于STM32的USB程序開發(fā)筆記_第4頁
基于STM32的USB程序開發(fā)筆記_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、基于STM32的USB程序開發(fā)筆記第一篇:需要準(zhǔn)備的一些資料 1基于STM32的USB程序開發(fā)筆記(三) STM32 USB固件函數(shù)的一些介紹 4基于 STM32 的 USB 程序開發(fā)筆記 (四) USB 設(shè)備的枚舉(上) 12第五篇: USB 設(shè)備的枚舉(下) 15第六篇: XP 下 USB 驅(qū)動開發(fā)的初步準(zhǔn)備工作 23第七篇: XP 下 USB 驅(qū)動開發(fā)的最終完成 30第一篇:需要準(zhǔn)備的一些資料1:STM32 的參考手冊, 這對于設(shè)備底層 USB 的硬件配置以及事件驅(qū)動機制的了解尤為重要, 你需要了解各個寄存器的功能以及如何操作,比如 CNTR 、ISTR 、EPnR 、DADDR 等等,

2、如果你想學(xué)習(xí) USB ,這個手冊是必須的。2:USB2.0 協(xié)議,這個資料同樣必不可少,如果因為英語閱讀能力而苦苦尋找中文版的USB2.0 協(xié)議,建議不要這么做,現(xiàn)在網(wǎng)絡(luò)中的所謂的中文版的 USB2.0 協(xié)議不是官方撰寫的,大多數(shù)是一些熱心朋友自己 翻譯的,卻不是很全面, 如果你在為尋找這類的資料而無所獲時, 建議認(rèn)真塌實的看看官方英文版的 USB2.0 協(xié)議,官方協(xié)議闡述的十分詳細(xì), 650 多頁,一字一句的了解全部協(xié)議不太可行,可針對性的重點理解, 比如對第 9 章 USB Device Framework 的詳細(xì)理解對于你的 USB Device 固件開發(fā)不可缺少(這里就是 STM32

3、)。3 : ST 提供的 USB 固件庫,這個類庫較為散亂,但不可不參考以下是最近這段時間的成果,包含固件、驅(qū)動以及應(yīng)用程序,固件部分有些功能是不被支持的,如SR_SetDescriptor() 、 SR_SynchFrame() 等等,在此說明戰(zhàn)士不支持非故意如此,而是還沒時間仔細(xì)深入編寫完善,因為這些目前不被支持的部分目前不被使用到。后序?qū)⒔又鴮Ω鱾€部分進(jìn)行一些說明,希望朋友們多多支持,同時歡迎朋友們討論。 如果你使用的是萬利的 STM3210B-LK1 開發(fā)板,則可以燒寫 hex 文件后進(jìn)行測試。下載該文件請參閱:第 2 篇:STM32 USB固件函數(shù)的驅(qū)動原理首先需要了解一個概念:US

4、B 設(shè)備( DEVICE )從來只是被動觸發(fā), USB 主機( HOST )掌握主動權(quán),發(fā)送什么數(shù)據(jù),什么時候發(fā) 送,是給設(shè)備數(shù)據(jù)還是從設(shè)備請求數(shù)據(jù),都是由 USB 主機完成的, USB 設(shè)備只是配合主機完成設(shè)備的枚 舉、數(shù)據(jù)方向和大小。根據(jù)數(shù)據(jù)特性再決定該不該回復(fù)該如何回復(fù)、該不該接收該如何接收這些動作。了解這些, 再仔細(xì)查看 STM32 的參考手冊 USB 部分以及 STM32 的中斷向量表, 從中可以找到兩個中斷:/* Function Name : USB_HP_CAN_TX_IRQHandler* Description : This function handles USB Hig

5、h Priority or CAN TX interrupts* requests.* Input : None* Output : None* Return : None*void USB_HP_CAN_TX_IRQHandler(void)USB_HPI();/* Function Name : USB_LP_CAN_RX0_IRQHandler* Description : This function handles USB Low Priority or CAN RX0 interrupts* requests.* Input: None* Output: None* Return:

6、None*/void USB_LP_CAN_RX0_IRQHandler(void)USB_LPI();即 USB 的高、低優(yōu)先權(quán)中斷處理函數(shù), 這也是整個 STM32 USB 的事件驅(qū)動源, USB_HPI() 與 USB_LPI() 既而轉(zhuǎn)向 usb_core(.c,.h) 進(jìn)行相關(guān)處理。中斷傳輸 (interrupt) 、控制傳輸 (control) 、大流量傳輸 (bulk) 由 USB_LPI() 響應(yīng),大流量傳輸 (bulk) 同樣可能響應(yīng) USB_HPI() ,同步傳輸 (isochronous) 只響應(yīng) USB_HPI()這樣響應(yīng) USB 的所有請求只需要關(guān)注 usb_core

7、.c 文件中的 USB_LPI() 與 USB_HPI() 函數(shù)。由于本人也是 對 USB 剛剛有所了解,因而在本例筆記中 USB_HPI() 函數(shù)未做任何處理,在此開源希望大家能完善與糾 正錯誤并能共享喜悅。以下是 USB_LPI() 函數(shù):/*/ Function Name : USB_LPI./ Description: Low Priority Interrupts service routine./ Input:/ Output:/ Return:*void USB_LPI(void)unsigned short wValISTR = GetISTR();#if(CNTR_MASK

8、& ISTR_RESET) / Resetif(wValISTR & ISTR_RESET & vwInterruptMask)SetISTR(CLR_RESET);INT_ISTR_RESET();#endif#if(CNTR_MASK & ISTR_DOVR) / DMA Over/Underrunif(wValISTR & ISTR_DOVR & vwInterruptMask)SetISTR(CLR_DOVR);INT_ISTR_DOVR();#endif#if(CNTR_MASK & ISTR_ERR) / Errorif(wValISTR & ISTR_ERR & vwInterr

9、uptMask)SetISTR(CLR_ERR);INT_ISTR_ERROR();#endif#if(CNTR_MASK & ISTR_WKUP) / Wakeup if(wValISTR & ISTR_WKUP & vwInterruptMask) SetISTR(CLR_WKUP);INT_ISTR_WAKEUP();#endif#if(CNTR_MASK & ISTR_SUSP) / Suspend if(wValISTR & ISTR_SUSP & vwInterruptMask) INT_ISTR_SUSPEND();SetISTR(CLR_SUSP); / must be don

10、e after setting of CNTR_FSUSP#endif#if(CNTR_MASK & ISTR_SOF) / Start Of Frameif(wValISTR & ISTR_SOF & vwInterruptMask)SetISTR(CLR_SOF);INT_ISTR_SOF();#endif#if(CNTR_MASK & ISTR_ESOF) / Expected Start Of Frameif(wValISTR & ISTR_ESOF & vwInterruptMask)SetISTR(CLR_ESOF);INT_ISTR_ESOF();#endif#if(CNTR_M

11、ASK & ISTR_CTR) / Correct Transferif(wValISTR & ISTR_CTR & vwInterruptMask)INT_ISTR_CTR();#endif/*/ Function Name : USB_HPI./ Description : High Priority Interrupts service routine./ Input:/ Output:/ Return:*void USB_HPI(void)可以看出, 在 USB_LPI() 函數(shù)中,根據(jù) STM32 USB 的中斷狀態(tài)寄存器( ISTR )的標(biāo)志位的狀態(tài)以及定義 的 USB 控制寄存器

12、中斷事件屏蔽碼, 響應(yīng)各自的中斷事件 ,比如 INT_ISTR_RESET() 響應(yīng) USB 的復(fù)位中 斷,一般可在此函數(shù)內(nèi)進(jìn)行 USB 的寄存器的初始化; INT_ISTR_CTR() 響應(yīng)一次正確的數(shù)據(jù)傳輸中斷,故 名思意,在完成一次正確的數(shù)據(jù)傳輸操作后,就會響應(yīng)此函數(shù)。具體含義請仔細(xì)查閱 STM32 參考手冊,下篇將針對這些響應(yīng)函數(shù)進(jìn)行逐一的詳細(xì)介紹?;赟TM32的USB程序開發(fā)筆記(三) STM32USB固件函數(shù)的一些介紹接著上篇,詳細(xì)情況可以查看 usb_core(.c/.h) , STM32 USB 中斷事件為以下幾種 :void ISTR_CTR(void);void ISTR

13、_SOF(void);void ISTR_ESOF(void);void ISTR_DOVR(void);void ISTR_ERROR(void);void ISTR_RESET(void);void ISTR_WAKEUP(void);void ISTR_SUSPEND(void);這些處理函數(shù)使能由定義 CNTR_MASK 決定:/ CNTR mask control#define CNTR_MASK CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_SOFM | CNTR_ESOFM | CNTR_RESETM | CNTR_

14、DOVRM 其中著重說明的是ISTR_RESET()和ISTR_CTR()函數(shù),ISTR_RESET()主要處理USB復(fù)位后進(jìn)行一些初始 化任務(wù), ISTR_CTR() 則是處理數(shù)據(jù)正確傳輸后控制,比如說響應(yīng)主機。/ */ Function Name : INT_ISTR_RESET/ Description : ISTR Reset Interrupt service routines./ Input :/ Output:/ Return: / *void INT_ISTR_RESET(void)/ Set the buffer table addressSetBTABLE(BASEADDR

15、_BTABLE);/ Set the endpoint type: ENDP0SetEPR_Type(ENDP0, EP_CONTROL);Clr_StateOut(ENDP0);/ Set the endpoint data buffer address: ENDP0 RXSetBuffDescTable_RXCount(ENDP0, ENDP0_PACKETSIZE);SetBuffDescTable_RXAddr(ENDP0, ENDP0_RXADDR);/ Set the endpoint data buffer address: ENDP0 TXSetBuffDescTable_TX

16、Count(ENDP0, 0);SetBuffDescTable_TXAddr(ENDP0, ENDP0_TXADDR);/ Initialize the RX/TX status: ENDP0SetEPR_RXStatus(ENDP0, EP_RX_VALID);SetEPR_TXStatus(ENDP0, EP_TX_NAK);/ / TODO: Add you code here/ / Set the endpoint type: ENDP1SetEPR_Type(ENDP1, EP_INTERRUPT); Clr_StateOut(ENDP1);/ Set the endpoint d

17、ata buffer address: ENDP1 RXSetBuffDescTable_RXCount(ENDP1, ENDP1_PACKETSIZE); SetBuffDescTable_RXAddr(ENDP1, ENDP1_RXADDR);/ Set the endpoint data buffer address: ENDP1 TX SetBuffDescTable_TXCount(ENDP1, 0);SetBuffDescTable_TXAddr(ENDP1, ENDP1_TXADDR);/ Initialize the RX/TX status: ENDP1SetEPR_RXSt

18、atus(ENDP1, EP_RX_VALID);SetEPR_TXStatus(ENDP1, EP_TX_DIS);/ Set the endpoint address: ENDP1 SetEPR_Address(ENDP1, ENDP1);SetEPR_Type(ENDP2, EP_INTERRUPT);Clr_StateOut(ENDP2);/ Set the endpoint data buffer address: ENDP2 RX SetBuffDescTable_RXCount(ENDP2, ENDP2_PACKETSIZE);SetBuffDescTable_RXAddr(EN

19、DP2, ENDP2_RXADDR);/ Set the endpoint data buffer address: ENDP2 TX SetBuffDescTable_TXCount(ENDP2, 0);SetBuffDescTable_TXAddr(ENDP2, ENDP2_TXADDR);/ Initialize the RX/TX status: ENDP2SetEPR_RXStatus(ENDP2, EP_RX_DIS);SetEPR_TXStatus(ENDP2, EP_TX_VALID);/ Set the endpoint address: ENDP2SetEPR_Addres

20、s(ENDP2, ENDP2);/ End of you code/ SetDADDR(0x0080 | vsDeviceInfo.bDeviceAddress); vsDeviceInfo.eDeviceState = DS_DEFAULT;vsDeviceInfo.bCurrentFeature = 0x00; vsDeviceInfo.bCurrentConfiguration = 0x00;vsDeviceInfo.bCurrentInterface = 0x00; vsDeviceInfo.bCurrentAlternateSetting = 0x00;vsDeviceInfo.uS

21、tatusInfo.w = 0x0000;在這個ISTR_CTR()函數(shù)中,定義了 EPO、1、2的傳輸方式以及各自的緩沖描述符,其中EPO是默認(rèn)端口,負(fù)責(zé)完成 USB 設(shè)備的枚舉,一般情況是不需要更改的。其他端點配置則需根據(jù)實際應(yīng)用而決定,如何設(shè)置 請仔細(xì)理解 STM32 的參考手冊。值得說明的是STM32的端點RX/TX緩沖描述表是定義在 PMA中的,他是基于分組緩沖區(qū)描述報表寄存器 (BTABLE)而定位的,各端點 RX/TX緩沖描述表說明是數(shù)據(jù)存儲地址以及大小,這個概念需要了解,ST提供的固件很含糊,為此,我在 usb_regs.h 文件中進(jìn)行了重新定義,如下:/ USB_IP Pac

22、ket Memory Area base address#define PMAAddr (Ox4OOO6OOOL) / Buffer Table address register#define BTABLE (volatile unsigned *)(RegBase + Ox5O)/* / Packet memory area: Total 512Bytes/ *#define BASEADDR_BTABLE OxOOOO/* / PMAAddr + BASEADDR_BTABLE + OxOOOOOOOO : EPO_TX_ADDR/ PMAAddr + BASEADDR_BTABLE +

23、OxOOOOOOO2 : EPO_TX_COUNT / PMAAddr + BASEADDR_BTABLE + OxOOOOOOO4 : EPO_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + OxOOOOOOO6 : EPO_RX_COUNT/ / PMAAddr + BASEADDR_BTABLE + OxOOOOOOO8 : EP1_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + OxOOOOOOOA : EP1_TX_COUNT / PMAAddr + BASEADDR_BTABLE + OxOOOOOOOC : EP1_RX_ADD

24、R/ PMAAddr + BASEADDR_BTABLE + OxOOOOOOOE : EP1_RX_COUNT/ / PMAAddr + BASEADDR_BTABLE + OxOOOOOO1O : EP2_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + OxOOOOOO12 : EP2_TX_COUNT / PMAAddr + BASEADDR_BTABLE + OxOOOOOO14 : EP2_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + OxOOOOOO16 : EP2_RX_COUNT/ PMAAddr + BASEADDR_BT

25、ABLE + 0x00000018 : EP3_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x0000001A : EP3_TX_COUNT / PMAAddr + BASEADDR_BTABLE + 0x0000001C : EP3_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x0000001E : EP3_RX_COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000020 : EP4_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x00000022 : EP4_TX_

26、COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000024 : EP4_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x00000026 : EP4_RX_COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000028 : EP5_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x0000002A : EP5_TX_COUNT / PMAAddr + BASEADDR_BTABLE + 0x0000002C : EP5_RX_ADDR/ PMAAddr + BASEADDR_B

27、TABLE + 0x0000002E : EP5_RX_COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000030 : EP6_TX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x00000032 : EP6_TX_COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000034 : EP6_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x00000036 : EP6_RX_COUNT/ PMAAddr + BASEADDR_BTABLE + 0x00000038 : EP7_TX

28、_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x0000003A : EP7_TX_COUNT / PMAAddr + BASEADDR_BTABLE + 0x0000003C : EP7_RX_ADDR/ PMAAddr + BASEADDR_BTABLE + 0x0000003E : EP7_RX_COUNT/ */ / PMAAddr + BASEADDR_BTABLE + (0x00000040 - 0x000001FF) : assigned to data buffer / * #define BASEADDR_DATA (BASEADDR_BTABLE

29、+ 0x00000040) / ENP0 #define ENDP0_PACKETSIZE 0x40#define ENDP2_RXADDR(ENDP1_TXADDR + ENDP1_PACKETSIZE)#define ENDP0_RXADDRBASEADDR_DATA#define ENDP0_TXADDR(ENDP0_RXADDR + ENDP0_PACKETSIZE)/ ENP1#define ENDP1_PACKETSIZE 0x40#define ENDP1_RXADDR(ENDP0_TXADDR + ENDP0_PACKETSIZE)#define ENDP1_TXADDR(EN

30、DP1_RXADDR + ENDP1_PACKETSIZE)/ ENP2#define ENDP2_PACKETSIZE 0x40#define ENDP2_TXADDR(ENDP2_RXADDR + ENDP2_PACKETSIZE)/ ENP3#define ENDP3_PACKETSIZE 0x40#define ENDP3_RXADDR(ENDP2_TXADDR + ENDP2_PACKETSIZE)#define ENDP3_TXADDR(ENDP3_RXADDR + ENDP3_PACKETSIZE)/ ENP4#define ENDP4_PACKETSIZE 0x40#defin

31、e ENDP4_RXADDR(ENDP3_TXADDR + ENDP3_PACKETSIZE)#define ENDP4_TXADDR(ENDP4_RXADDR + ENDP4_PACKETSIZE)/ ENP5#define ENDP5_PACKETSIZE 0x40#define ENDP5_RXADDR(ENDP4_TXADDR + ENDP4_PACKETSIZE)#define ENDP5_TXADDR(ENDP5_RXADDR + ENDP5_PACKETSIZE)/ ENP6#define ENDP6_PACKETSIZE 0x40#define ENDP6_RXADDR#def

32、ine ENDP6_TXADDR(ENDP5_TXADDR + ENDP5_PACKETSIZE)(ENDP6_RXADDR + ENDP6_PACKETSIZE)/ ENP7#define ENDP7_PACKETSIZE 0x40#define ENDP7_RXADDR(ENDP6_TXADDR + ENDP6_PACKETSIZE)#define ENDP7_TXADDR(ENDP7_RXADDR + ENDP7_PACKETSIZE)這樣,一般只要在 PMA 的大小區(qū)域內(nèi)( 512Bytes ),修改端點 EPnR 的數(shù)據(jù)包大小就可以了,當(dāng)然,實際 情況可以根據(jù)需要進(jìn)行更改。/*/ F

33、unction Name : INT_ISTR_CTR/ Description : ISTR Correct Transfer Interrupt service routine. / Input:/ Output:/ Return:/ *void INT_ISTR_CTR(void)unsigned short wEPIndex;unsigned short wValISTR;unsigned short wValENDP;while( (wValISTR=GetISTR() & ISTR_CTR) != 0 )/ Get the index number of the endpoints

34、wEPIndex = wValISTR & ISTR_EP_ID;if(wEPIndex = 0)/ Set endpoint0 RX/TX status: NAK (Negative-Acknowlegment)SetEPR_RXStatus(ENDP0, EP_RX_NAK);SetEPR_TXStatus(ENDP0, EP_TX_NAK);/ Transfer directionif(wValISTR & ISTR_DIR) = 0)/ DIR=0: IN/ DIR=0 implies that EP_CTR_TX always 1ClrEPR_CTR_TX(ENDP0);CTR_IN

35、0(); return;else/ DIR=1: SETUP or OUT/ DIR=1 implies that CTR_TX or CTR_RX always 1 wValENDP = GetEPR(ENDP0);if(wValENDP & EP_CTR_TX) != 0)ClrEPR_CTR_TX(ENDP0);CTR_IN0();return;else if(wValENDP & EP_SETUP) != 0)ClrEPR_CTR_RX(ENDP0);CTR_SETUP0();return;else if(wValENDP & EP_CTR_RX) != 0)ClrEPR_CTR_RX

36、(ENDP0);CTR_OUT0();return;/ Other endpoints elsewValENDP = GetEPR(wEPIndex);SetEPR_RXStatus(wEPIndex, EP_RX_NAK);SetEPR_TXStatus(wEPIndex, EP_TX_NAK);if(wValENDP & EP_CTR_TX) != 0) ClrEPR_CTR_TX(wEPIndex); switch(wEPIndex)case ENDP1: CTR_IN1(); break; case ENDP2: CTR_IN2(); break; case ENDP3: CTR_IN

37、3(); break; case ENDP4: CTR_IN4(); break; case ENDP5: CTR_IN5(); break; case ENDP6: CTR_IN6(); break; case ENDP7: CTR_IN7(); break; default: break;if(wValENDP & EP_CTR_RX) != 0) ClrEPR_CTR_RX(wEPIndex); switch(wEPIndex)case ENDP1: CTR_OUT1(); break;case ENDP2: CTR_OUT2(); break;case ENDP3: CTR_OUT3(

38、); break;case ENDP4: CTR_OUT4(); break;case ENDP5: CTR_OUT5(); break;case ENDP6: CTR_OUT6(); break;case ENDP7: CTR_OUT7(); break; default: break;INT_ISTR_CTR() 函數(shù)將各自響應(yīng)事件提取出來,默認(rèn)端點EP0 也是最為復(fù)雜的,這個需要查看 STM32 的參考手冊以及USB協(xié)議才能更好了解為何如此。到這里STM32 USB里數(shù)據(jù)傳輸事件就指向了各個對應(yīng)的端點。下篇著重說明 USB 設(shè)備的枚舉?;赟TM32的USB程序開發(fā)筆記(四)一一USB設(shè)

39、備的枚舉上)USB 設(shè)備能否工作,枚舉步驟,用 “鄉(xiāng)村愛情 ”里的話說, “必須的! ”,網(wǎng)上也有很多資料,圈圈就提供了一 份詳細(xì)的枚舉過程,但對 STM32 是怎么響應(yīng)的沒有說明,一會詳細(xì)道來,先上圈圈的提供的那個枚舉圖 示,希望圈圈支持,如果不妥,請與我聯(lián)系,謝謝。我將此轉(zhuǎn)換成了 PDF 文件,方便查看。 首先說明一個變量,定義在 usb_core.c 中: volatile DEVICE_INFO vsDeviceInfo;看意思就知道他的作用了, DEVICE_INFO 是個結(jié)構(gòu),定義在 usb_type.h 中:/* / DEVICE_INFO/* typedef struct _D

40、EVICE_INFO unsigned char bDeviceAddress;unsigned char bCurrentFeature; unsigned char bCurrentConfiguration;unsigned char bCurrentInterface; unsigned char bCurrentAlternateSetting;WORD_2BYTE uStatusInfo;DEVICE_STATE eDeviceState; RESUME_STATE eResumeState;CONTROL_STATE eControlState;SETUP_DATA SetupD

41、ata;TRANSFER_INFO TransInfo;DEVICE_INFO, *PDEVICE_INFO;在枚舉過程中,就是如何處理好 SETUP 事件,如果 STM32 USB 接收到正確的 SETUP 事件,將響應(yīng)函 數(shù) CTR_SETUP0() ,SETUP 事件是特殊的 OUT 事件,數(shù)據(jù)方向 Host-Device ,SETUP 事件數(shù)據(jù)長度固 定為 8,數(shù)據(jù)定義在 DEVICE_INFO.SetupData ,其數(shù)據(jù)結(jié)構(gòu)是 (定義在 usb_type.h 中 ): typedef struct _SETUP_DATAunsigned char bmRequestType; /

42、request type unsigned char bRequest; / request codeWORD_2BYTE wValue;WORD_2BYTE wIndex;WORD_2BYTE wLength; SETUP_DATA, *PSETUP_DATA;WORD_2BYTE 是定義的一個共用體: typedef union _WORD_2BYTE unsigned short w;structunsigned char LSB;unsigned char MSB;b;WORD_2BYTE;為什么將 SETUP 數(shù)據(jù)結(jié)構(gòu)中的 wValue,wIndex,wLength 如此定義?1:

43、USB 協(xié)議中所有數(shù)據(jù)傳輸都是依照低位在先的原則2:高地位字節(jié)可能功能復(fù)用 這樣在后續(xù)的程序編寫中就變得十分方便, ST 提供的 USB 固件方法同樣如此,但這方面的處理讓人有些 摸不著頭腦,詳情可參閱。至于具體的 SETUP 數(shù)據(jù)結(jié)構(gòu)含義如何,還是要具備基本知識:了解 USB 協(xié)議CTR_SETUP0() 函數(shù)將 SETUP 數(shù)據(jù)提取出來, SETUP 數(shù)據(jù)結(jié)構(gòu)有 0 長度和非 0 長度的數(shù)據(jù)結(jié)構(gòu),詳細(xì) 參閱 USB2.0 官方協(xié)議第 9 章。在這將兩種區(qū)別開來分別執(zhí)行 SETUP0_NoData() 和 SETUP0_Data() 函數(shù), 并返回結(jié)果,根據(jù)返回結(jié)果再響應(yīng) USB 主機/*

44、/ Function Name : CTR_SETUP0 / Description/ Input/ Output/ Return/* void CTR_SETUP0(void) RESULT eResult;BufferCopy_PMAToUser( (unsigned char *)&vsDeviceInfo.SetupData,GetBuffDescTable_RXAddr(ENDP0),GetBuffDescTable_RXCount(ENDP0);if(vsDeviceInfo.SetupData.wLength.w = 0) eResult = SETUP0_NoData();el

45、seeResult = SETUP0_Data();switch(eResult)case RESULT_SUCCESS:break;case RESULT_LASTDATA:break;case RESULT_ERROR:case RESULT_UNSUPPORT:SetEPR_RXStatus(ENDP0, EP_RX_VALID);SetEPR_TXStatus(ENDP0, EP_TX_STALL);break;SETUP0_Data() 和 SETUP0_NoData() 函數(shù)支持的所有 USB 請求類型只有羅列的這些,有多少種組合都 定義在 USB 協(xié)議中,程序根據(jù)請求代碼,再去執(zhí)

46、行對應(yīng)函數(shù),這樣做的目的就是讓程序結(jié)構(gòu)明了。其中注 釋為/ done 的部分表明此部分功能已完成。對于未完成部分,希望大家在交流中完善。/* / Routine Groups: SETUP_Data/*RESULT SETUP0_Data(void)/ SetupData.bRequest: request code switch(vsDeviceInfo.SetupData.bRequest)case SR_GET_STATUS:return SR_GetStatus();/ donecase SR_GET_DESCRIPTOR: return SR_GetDescriptor();/ do

47、necase SR_SET_DESCRIPTOR: return SR_SetDescriptor(); / unsupportcase SR_GET_CONFIGURATION: return SR_GetConfiguration(); / done case SR_GET_INTERFACE: return SR_GetInterface(); / unsupport case SR_SYNCH_FRAME:return SR_SynchFrame();/ unsupportdefault: return RESULT_UNSUPPORT;/*/ Routine Groups: SETU

48、P_NoData/*RESULT SETUP0_NoData(void)/ SetupData.bRequest: request code switch(vsDeviceInfo.SetupData.bRequest)case SR_CLEAR_FEATURE: return SR_ClearFeature(); / unsupport case SR_SET_FEATURE: return SR_SetFeature(); / unsupport case SR_SET_ADDRESS: return SR_SetAddress(); / done case SR_SET_CONFIGURATION:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論