?? usbcore.c
字號:
break;
}
//判斷請求的字節(jié)數是否比實際需要發(fā)送的字節(jié)數多
//如果請求的比實際的長,那么只返回實際長度的數據
if(wLength>SendLength)
{
if(SendLength%DeviceDescriptor[7]==0) //并且剛好是整數個數據包時
{
NeedZeroPacket=1; //需要返回0長度的數據包
}
}
else
{
SendLength=wLength;
}
//將數據通過EP0返回
UsbEp0SendData();
break;
case REPORT_DESCRIPTOR: //報告描述符
#ifdef DEBUG0
Prints("報告描述符。\r\n");
#endif
//獲取報告描述符時,wIndex中保存的是請求的接口號。
//我們這里有兩個接口,接口0用來實現鍵盤,接口1實現鼠標。
switch(wIndex)
{
case 0: //發(fā)送到接口0的請求
pSendData=KeyboardReportDescriptor; //需要發(fā)送的數據為報告描述符
SendLength=sizeof(KeyboardReportDescriptor); //需要返回的數據長度
break;
case 1: //發(fā)送到接口1的請求
pSendData=MouseReportDescriptor; //需要發(fā)送的數據為報告描述符
SendLength=sizeof(MouseReportDescriptor); //需要返回的數據長度
break;
default : //其它為未定義的接口,返回0長度數據包
SendLength=0;
NeedZeroPacket=1;
break;
}
//判斷請求的字節(jié)數是否比實際需要發(fā)送的字節(jié)數多
//如果請求的比實際的長,那么只返回實際長度的數據
if(wLength>SendLength)
{
if(SendLength%DeviceDescriptor[7]==0) //并且剛好是整數個數據包時
{
NeedZeroPacket=1; //需要返回0長度的數據包
}
}
else
{
SendLength=wLength;
}
//將數據通過EP0返回
UsbEp0SendData();
break;
default: //其它描述符
#ifdef DEBUG0
Prints("其他描述符,描述符代碼:");
PrintHex((wValue>>8)&0xFF);
Prints("\r\n");
#endif
break;
}
break;
case GET_INTERFACE: //獲取接口
#ifdef DEBUG0
Prints("獲取接口。\r\n");
#endif
break;
case GET_STATUS: //獲取狀態(tài)
#ifdef DEBUG0
Prints("獲取狀態(tài)。\r\n");
#endif
break;
case SYNCH_FRAME: //同步幀
#ifdef DEBUG0
Prints("同步幀。\r\n");
#endif
break;
default: //未定義的標準請求
#ifdef DEBUG0
Prints("錯誤:未定義的標準輸入請求。\r\n");
#endif
break;
}
break;
case 1: //類請求
#ifdef DEBUG0
Prints("USB類輸入請求:\r\n");
#endif
break;
case 2: //廠商請求
#ifdef DEBUG0
Prints("USB廠商輸入請求:\r\n");
#endif
break;
default: //未定義的請求。這里只顯示一個報錯信息。
#ifdef DEBUG0
Prints("錯誤:未定義的輸入請求。\r\n");
#endif
break;
}
}
//否則說明是輸出請求
else //if(bmRequestType&0x80==0x80)之else
{
//根據bmRequestType的D6~5位散轉,D6~5位表示請求的類型
//0為標準請求,1為類請求,2為廠商請求。
switch((bmRequestType>>5)&0x03)
{
case 0: //標準請求
#ifdef DEBUG0
Prints("USB標準輸出請求:");
#endif
//USB協議定義了幾個標準輸出請求,我們實現這些標準請求即可
//請求的代碼在bRequest中,對不同的請求代碼進行散轉
switch(bRequest)
{
case CLEAR_FEATURE: //清除特性
#ifdef DEBUG0
Prints("清除特性。\r\n");
#endif
break;
case SET_ADDRESS: //設置地址
#ifdef DEBUG0
Prints("設置地址。地址為:");
PrintHex(wValue&0xFF); //顯示所設置的地址
Prints("\r\n");
#endif
D12SetAddress(wValue&0xFF); //wValue中的低字節(jié)是設置的地址值
//設置地址沒有數據過程,直接進入到狀態(tài)過程,返回一個0長度的數據包
SendLength=0;
NeedZeroPacket=1;
//將數據通過EP0返回
UsbEp0SendData();
break;
case SET_CONFIGURATION: //設置配置
#ifdef DEBUG0
Prints("設置配置。\r\n");
#endif
//使能非0端點。非0端點只有在設置為非0的配置后才能使能。
//wValue的低字節(jié)為配置的值,如果該值為非0,才能使能非0端點。
//保存當前配置值
ConfigValue=wValue&0xFF;
D12SetEndpointEnable(ConfigValue);
//返回一個0長度的狀態(tài)數據包
SendLength=0;
NeedZeroPacket=1;
//將數據通過EP0返回
UsbEp0SendData();
break;
case SET_DESCRIPTOR: //設置描述符
#ifdef DEBUG0
Prints("設置描述符。\r\n");
#endif
break;
case SET_FEATURE: //設置特性
#ifdef DEBUG0
Prints("設置特性。\r\n");
#endif
break;
case SET_INTERFACE: //設置接口
#ifdef DEBUG0
Prints("設置接口。\r\n");
#endif
break;
default: //未定義的標準請求
#ifdef DEBUG0
Prints("錯誤:未定義的標準輸出請求。\r\n");
#endif
break;
}
break;
case 1: //類請求
#ifdef DEBUG0
Prints("USB類輸出請求:");
#endif
switch(bRequest)
{
case SET_IDLE:
#ifdef DEBUG0
Prints("設置空閑。\r\n");
#endif
//只需要返回一個0長度的數據包即可
SendLength=0;
NeedZeroPacket=1;
//將數據通過EP0返回
UsbEp0SendData();
break;
default:
#ifdef DEBUG0
Prints("未知請求。\r\n");
#endif
break;
}
break;
case 2: //廠商請求
#ifdef DEBUG0
Prints("USB廠商輸出請求:\r\n");
#endif
break;
default: //未定義的請求。這里只顯示一個報錯信息。
#ifdef DEBUG0
Prints("錯誤:未定義的輸出請求。\r\n");
#endif
break;
}
}
}
//普通數據輸出
else //if(D12ReadEndpointLastStatus(0)&0x20)之else
{
D12ReadEndpointBuffer(0,16,Buffer);
D12ClearBuffer();
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函數功能:端點0輸入中斷處理函數。
入口參數:無。
返 回:無。
備 注:無。
********************************************************************/
void UsbEp0In(void)
{
#ifdef DEBUG0
Prints("USB端點0輸入中斷。\r\n");
#endif
//讀最后發(fā)送狀態(tài),這將清除端點0的中斷標志位
D12ReadEndpointLastStatus(1);
//發(fā)送剩余的字節(jié)數
UsbEp0SendData();
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函數功能:端點1輸出中斷處理函數。
入口參數:無。
返 回:無。
備 注:無。
********************************************************************/
void UsbEp1Out(void)
{
uint8 Buf[2]; //用來保存2字節(jié)的輸出報告,控制LED。
#ifdef DEBUG0
Prints("USB端點1輸出中斷。\r\n");
#endif
//讀端點最后狀態(tài),這將清除端點1輸出的中斷標志位
D12ReadEndpointLastStatus(2);
//從端點1輸出緩沖讀回2字節(jié)數據
D12ReadEndpointBuffer(2,2,Buf);
//清除端點緩沖區(qū)
D12ClearBuffer();
//注意輸出報告也增加了一字節(jié)的報告ID。
//第1字節(jié)為報告ID,第2字節(jié)為LED狀態(tài),某位為1時,表示LED亮。
//我們定義的鍵盤的報告ID為1,所以這里判斷一下報告ID是否為1。
if(Buf[0]==0x01) //報告ID為1,即鍵盤的輸出報告
{
LEDs=~Buf[1];
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函數功能:端點1輸入中斷處理函數。
入口參數:無。
返 回:無。
備 注:無。
********************************************************************/
void UsbEp1In(void)
{
#ifdef DEBUG0
Prints("USB端點1輸入中斷。\r\n");
#endif
//讀最后發(fā)送狀態(tài),這將清除端點1輸入的中斷標志位
D12ReadEndpointLastStatus(3);
//端點1輸入處于空閑狀態(tài)
Ep1InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函數功能:端點2輸出中斷處理函數。
入口參數:無。
返 回:無。
備 注:無。
********************************************************************/
void UsbEp2Out(void)
{
#ifdef DEBUG0
Prints("USB端點2輸出中斷。\r\n");
#endif
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函數功能:端點2輸入中斷處理函數。
入口參數:無。
返 回:無。
備 注:無。
********************************************************************/
void UsbEp2In(void)
{
#ifdef DEBUG0
Prints("USB端點2輸入中斷。\r\n");
#endif
//讀最后發(fā)送狀態(tài),這將清除端點2輸入的中斷標志位
D12ReadEndpointLastStatus(5);
//端點2輸入處于空閑狀態(tài)
Ep2InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -