中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
USB的“JoyStickMouse”工作過程詳細分析 (三)

1、枚舉第二步:設置地址

1)重新從復位狀態(tài)開始

在第一次獲取設備描述符后,程序使端點0的發(fā)送和接收都無效,狀態(tài)也設置為STALLED,所以主機先發(fā)一個復位,使得端點0接收有效。雖然說在NAKSTALL狀態(tài)下,端點仍然可以響應和接收SETUP包。

2)設置地址的建立階段:

主機先發(fā)一個SETUP令牌包,設備端EP0SETUP標志置位。然后主機發(fā)了一個OUT包,共8個字節(jié),里面包含設置地址的要求。

設備在檢驗數據后,發(fā)一個ACK握手包。同時CTR_RX置位,CTR置位。數據已經保存到RxADDR所指向的緩沖區(qū)。此時USB產生數據接收中斷。

由于CTR_RXSETUP同時置位,終端處理程序調用Setup0_Process(),所做的工作仍然是先填充pInformation結構,獲取請求特征碼、請求代碼和數據長度。

由于設置地址不會攜帶數據,所以接下來調用NoData_Setup0()。執(zhí)行以下代碼:

else if (RequestNo == SET_ADDRESS)

{

Result = USB_SUCCESS;

}

說明設置地址沒有做任何工作。

ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */

USB_StatusIn(); //這句話是一個關鍵,它是一個宏,實際是準備好發(fā)送0字節(jié)的狀態(tài)數據包。因為地址設置沒有數據過程,建立階段后直接進入狀態(tài)階段,主機發(fā)IN令牌包,設備返回0字節(jié)數據包,主機再ACK。

它對應的宏是這樣的:

#define USB_StatusIn() Send0LengthData() //準備發(fā)送0字節(jié)數據

#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \

vSetEPTxStatus(EP_TX_VALID); \ //設置發(fā)送有效,發(fā)送字節(jié)數為0

}

3)設置地址的狀態(tài)階段:

而前面把狀態(tài)設置為WAIT_STATUS_IN是給IN令牌包的處理提供指示。因為建立階段結束以后,主機接著發(fā)一個IN令牌包,設備返回0字節(jié)數據包后,進入中斷。

本次中斷由IN0_Process()函數來處理,追蹤進入,它執(zhí)行以下代碼:

else if (ControlState == WAIT_STATUS_IN)

{

if ((pInformation->USBbRequest == SET_ADDRESS) &&

(Type_Recipient==(STANDARD_REQUEST|DEVICE_RECIPIENT)))

{

SetDeviceAddress(pInformation->USBwValue0);

pUser_Standard_Requests->User_SetDeviceAddress(); //這個函數就一個賦值語句,bDeviceState = ADDRESSED。

}

(*pProperty->Process_Status_IN)(); //這是一個空函數。

ControlState = STALLED;

}

執(zhí)行設置地址操作、采用新地址后,把設備的狀態(tài)改為STALLED。而在處理的出口中調用Post0_Process()函數,這個所做的工作是:

SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

//將端點0的緩沖區(qū)大小設置為64字節(jié)

if (pInformation->ControlState == STALLED)

{

vSetEPRxStatus(EP_RX_STALL);

vSetEPTxStatus(EP_TX_STALL);

}

將端點0的發(fā)送和接收都設置為:STALL,這種狀態(tài)下只接受SETUP令牌包。

2、枚舉第三步:從新地址獲取設備描述符

1)上一階段末尾的狀態(tài)

端點0的發(fā)送和接收都設置為:STALL,只接收SETUP令牌包。

2)建立階段:主機發(fā)令牌包、數據包、設備ACK

產生數據接收中斷,且端點0SETUP置位,調用Setup0_Process()函數進行處理。

Setup0_Process()中,因為主機發(fā)送了請求數據8個字節(jié)。由調用Data_Setup0()函數進行處理。首先是獲取設備描述符的長度,描述符的起始地址,傳送的最大字節(jié)數,根據這些參數確定本次能夠傳輸的字節(jié)數,然后調用DataStageIn()函數進行實際的數據傳輸操作,設備描述符必須在本次中斷中就寫入發(fā)送緩沖區(qū),因為很快就要進入數據階段了。

在函數處理的最后:

vSetEPTxStatus(EP_TX_VALID);

USB_StatusOut();/*本來期待IN令牌包,但用戶可以取消數據階段,一般不會用到*/

3)數據階段:主機發(fā)IN包,設備返回數據,主機ACK

本次操作會產生數據發(fā)送完成中斷,由In0_Process(void)來處理中斷,它也調用DataStageIn()函數來進行處理。

如果數據已經發(fā)送完:

ControlState = WAIT_STATUS_OUT;

vSetEPTxStatus(EP_TX_STALL);

//轉入狀態(tài)階段。

有可能的話:

Send0LengthData();

ControlState = LAST_IN_DATA;

Data_Mul_MaxPacketSize = FALSE; //這一次發(fā)送0個字節(jié),狀態(tài)轉為最后輸入階段。

否則,繼續(xù)準備數據,調整剩余字節(jié)數、發(fā)送指針位置,等待主機的下一個IN令牌包。

4)狀態(tài)階段:主機發(fā)OUT包、0字節(jié)包,設備ACK

數據發(fā)送完成中斷,調用Out0_Process(void)函數進行處理,由于在數據階段的末尾已經設置設備狀態(tài)為:WAIT_STATUS_OUT,所以處理函數基本上沒有做什么事,就退出了。并將狀態(tài)設為STALLED

3、對配置描述符、字符串描述符獲取過程進行簡單跟蹤,過程就不再一一敘述了。

4、主機設置配置。

建立階段:主機發(fā)SETUP包、發(fā)請求數據包(DATA0包)、用戶ACK。

進入CTR中斷,用戶調用Setup0_Process()函數進行處理,取得請求數據后,由于沒有數據傳輸階段,該函數調用NoData_Setup0()函數進行處理。

判斷為設置配置后,調用Standard_SetInterface()函數將設備狀態(tài)結構體的當前配置改為主機數據中的配置參數。同時調用用戶的設置配置函數,將設備狀態(tài)改為“configured”。

退出時,將控制傳輸狀態(tài)改為:ControlState = WAIT_STATUS_IN,進入狀態(tài)階段。設備期待主機的IN令牌包,返回狀態(tài)數據。

狀態(tài)階段:主機發(fā)IN令牌、設備返回0[size=12p]Setup0_Process()函數進行處理,取得請求數據后,由于沒有數據傳輸階段,該函數調用NoData_Setup0()函數進行處理。

設置空閑時一個類特殊請求,其特征碼為0x21,2表示類請求而不是標準請求,1表示接收對象是接口而不是設備。

USB的底層并不支持類特殊請求,它將調用上層函數提供的函數:

if (Result != USB_SUCCESS)

{

Result = (*pProperty->Class_NoData_Setup)(RequestNo); //這里就是調用用戶提供的類特殊請求的處理函數。結果發(fā)現用戶提供的類特殊請求(針對無數據情況)只支持SET_PROTOCOL。針對有數據情況只支持:GET_PROTOCOL

if ((Type_Recipient==(CLASS_REQUEST | INTERFACE_RECIPIENT))

&& (RequestNo == SET_PROTOCOL))

{

return Joystick_SetProtocol();

}

}

6、主機獲取報告描述符

建立階段:主機發(fā)SETUP包、發(fā)請求數據包(DATA0包)、用戶ACK。

進入CTR中斷,獲取描述符是一個標準請求,但是報告描述符并不是需要通用實現的,所以在底層函數中沒有實現。跟蹤Setup0_Process(void)——進入Data_Setup(void)函數,它是這么處理的:

if (Request_No == GET_DESCRIPTOR)

{

if(Type_Recipient==(STANDARD_REQUEST| EVICE_RECIPIENT))

{

u8 wValue1 = pInformation->USBwValue1;

if (wValue1 == DEVICE_DESCRIPTOR)

{

CopyRoutine = pProperty->GetDeviceDescriptor;

}

else if (wValue1 == CONFIG_DESCRIPTOR)

{

CopyRoutine = pProperty->GetConfigDescriptor;

}

else if (wValue1 == STRING_DESCRIPTOR)

{

CopyRoutine = pProperty->GetStringDescriptor;

}

/* End of GET_DESCRIPTOR */

}

}

可見核心函數只支持設備描述符、配置描述符以及字符串描述符。最終該函數將調用:

Result= (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);

調用用戶的類特殊實現來獲取報告描述符,同時HID類描述符也是通過這種方式取得的。

7、主機從中斷端點讀取鼠標操作數據

主機會輪詢設備,設備數據的準備在主函數中,用Joystick_Send(JoyState())函數來實現。

Mouse_Buffer[1] = X;

Mouse_Buffer[2] = Y;

/*copy mouse position info in ENDP1 Tx Packet Memory Area*/

UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4);

/* enable endpoint for transmission */

SetEPTxValid(ENDP1);

使能端點1的發(fā)送,當主機的IN令牌包來的時候,SIE將數據返回給主機。同時產生CTR中斷。

在中斷處理程序中,執(zhí)行下列代碼:

if ((wEPVal & EP_CTR_TX) != 0)

{

/* clear int flag */

_ClearEP_CTR_TX(EPindex);

(*pEpInt_IN[EPindex-1])();

} /* if((wEPVal & EP_CTR_TX) != 0) */

這是在函數指針數組中調用函數,跟蹤進入:發(fā)現這個函數什么也沒有做。

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
基于STM32的USB枚舉過程學習筆記(二)
USB枚舉過程分析
USB固件開發(fā)總結(二)
基于STM32的USB學習筆記
USB相關知識
USB的八個問題和答案(適用初學者)--------轉帖??!謝謝原創(chuàng)者! 中國電子開發(fā)網(...
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服