📄 usb.c
字号:
//-------------------------------------------------------------------------------
uartpush("@@@@Packet: ");
ltoa(dReq.bmRequest,data,16);
uartpush(data);
uartpush(" ");
ltoa(dReq.bRequest,data,16);
uartpush(data);
uartpush(" ");
ltoa(dReq.wValue,data,16);
uartpush(data);
uartpush(" ");
ltoa(dReq.wIndex,data,16);
uartpush(data);
uartpush(" ");
ltoa(dReq.wLength,data,16);
uartpush(data);
uartpush("\n\r");
//-------------------------------------------------------------------------------
//end send debug data back to the pc through uart
//-------------------------------------------------------------------------------
switch (req_type) // Parse bmRequest Type
{
//---------------------------------------------------------------------
// Standard USB Requests
//---------------------------------------------------------------------
case STD_REQUEST:
// uartpush("______STD_REQUEST!\n\r");
switch (dReq.bRequest) // Parse bRequest
{
case GET_DESCRIPTOR:
//uartpush("________GET_DESCRIPTOR!\n\r");
switch ((B8)dReq.wValue) // Parse wValue
{
case DEVICE:
uartpush("____获取设备描述符!\n\r");
USBBufWrite(EP0A_Slave_Buf,(B8*)Dev_Descp,DEV_LEN); // load Device Descp
len_req = (len_req>=DEV_LEN) ? DEV_LEN:len_req; // get exact data length
break;
case CONFIGURATION:
uartpush("____获取配置描述符!\n\r");
USBBufWrite(EP0A_Slave_Buf,(B8*)Cfg_Descp,CFG_LEN); // load Config Descp
len_req = (len_req>=CFG_LEN) ? CFG_LEN:len_req; // get exact data length
break;
case HID_DEV:
uartpush("____获取HID_DEV描述符!\n\r");
USBBufWrite(EP0A_Slave_Buf,(B8*)Cfg_Descp+18,HID_LEN);// load HID Class Descp
len_req = (len_req>=HID_LEN) ? HID_LEN:len_req; // get exact data length
break;
case HID_REPORT:
uartpush("____获取HID_REPORT描述符!\n\r");
USBBufWrite(EP0A_Slave_Buf,(B8*)Rep_Descp,REP_LEN); // load Report Descp
len_req = (len_req>=REP_LEN) ? REP_LEN:len_req; // get exact data length
break;
case STRING:
uartpush("____获取字符串描述符!\n\r");
switch(dReq.wValue>>8) // get string index
{
case 0x00: USBBufWrite(EP0A_Slave_Buf,(B8*)LangString,LangString[0]);
// uartpush("____________LangString!\n\r");
len_req = (len_req>=LangString[0]) ? LangString[0]:len_req;
break;
case 0x01: USBBufWrite(EP0A_Slave_Buf,(B8*)MfgString,MfgString[0]);
// uartpush("____________MfgString!\n\r");
len_req = (len_req>=MfgString[0]) ? MfgString[0]:len_req;
break;
case 0x02: USBBufWrite(EP0A_Slave_Buf,(B8*)ProdString,ProdString[0]);
// uartpush("____________ProdString!\n\r");
len_req = (len_req>=ProdString[0]) ? ProdString[0]:len_req;
break;
}
break;
}
if (len_req == WordSwap(dReq.wLength)) // if requested length is equal to the
{
IN_EXACT = TRUE; // exact length of descriptor, set IN_EXACT
uartpush("exact\n\r");
} // is use during IN-NULL pkt trasnmission
len_xfr = (len_req>=EP0_LEN) ? EP0_LEN:(B8)len_req; // get current IN transfer length
EP0A_IN_Arm(EP0A_Slave_Buf,len_xfr,1); // Arm IN response, start with DATA1 seq
in_buffer_idx += len_xfr; // update to next muliple buffer location
len_req -= len_xfr; // update data length for current transfer
break;
case GET_CONFIG:
uartpush("____获取配置!\n\r");
USBWrite(EP0A_Slave_Buf,Slave_ConfigVal); // load current configuration value
EP0A_IN_Arm(EP0A_Slave_Buf,1,1); // send 1 byte data back to host
len_req = 0;
break;
case GET_INTERFACE:
uartpush("____获取接口!\n\r");
USBWrite(EP0A_Slave_Buf,Slave_IfcAlt[dReq.wIndex>>8]); // load current alternate setting
EP0A_IN_Arm(EP0A_Slave_Buf,1,1); // send 1 byte data back to host
len_req = 0;
break;
case GET_STATUS:
//uartpush("________GET_STATUS!\n\r");
switch(dReq.bmRequest&0x03) // check for recipients
{
case RECIPIENT_DEV: // load current device status
uartpush("____获取RECIPIENT_DEV状态!\n\r");
USBWrite(EP0A_Slave_Buf,(Slave_RemoteWU<<1)|BUS_POWERED);
break;
case RECIPIENT_IFC:
uartpush("____获取RECIPIENT_IFC状态!\n\r");
USBWrite(EP0A_Slave_Buf,0); // first byte = 0
break;
case RECIPIENT_ENP:
uartpush("____获取RECIPIENT_ENP状态!\n\r");
if((dReq.wIndex>>8) & 0x80) // for IN direction endpoint
{
if(Slave_inEPstall & (0x01<<((dReq.wIndex>>8)&0x0F)))
USBWrite(EP0A_Slave_Buf,1); // first byte = 1 (IN endpoint stall)
else
USBWrite(EP0A_Slave_Buf,0); // first byte = 0 (IN endpoint not stall)
}
else // for OUT direction endpoint
{
if(Slave_outEPstall & (0x01<<((dReq.wIndex>>8)&0x0F)))
USBWrite(EP0A_Slave_Buf,1); // first byte = 1 (OUT endpoint stall)
else
USBWrite(EP0A_Slave_Buf,0); // first byte = 0 (OUT endpoint not stall)
}
break;
}
USBWrite(EP0A_Slave_Buf+1,0); // second byte = 0
EP0A_IN_Arm(EP0A_Slave_Buf,2,1); // send 2 bytes data back to host
len_req = 0; // reset request length to zero
break;
case SET_FEATURE:
case CLEAR_FEATURE:
uartpush("____设置清除特性!\n\r");
switch(dReq.bmRequest&0x03) // check for recipients
{
case RECIPIENT_DEV:
//uartpush("__________RECIPIENT_DEV!\n\r");
if((dReq.wValue>>8) == 1) // feature selector = 1 (remote wakeup)
{
if(dReq.bRequest==SET_FEATURE) // set remote wake up status
Slave_RemoteWU = 1;
if(dReq.bRequest==CLEAR_FEATURE) // clear remote wake up status
Slave_RemoteWU = 0;
EP0A_IN_Arm(0,0,1); // IN status stage
}
else
USBWrite(EP0AControl,SEND_STALL); // Stall unsupported requests
break;
case RECIPIENT_ENP:
//uartpush("__________RECIPIENT_ENP!\n\r");
if((dReq.wValue>>8) == 0) // feature selector = 0 (endpoint stall)
{
if((dReq.wIndex>>8) & 0x80) // for IN direction endpoint
{
if(dReq.bRequest==SET_FEATURE) // set endpoint stall (limit to 7 IN's data endpoint)
Slave_inEPstall |= (0x01<<((dReq.wIndex>>8)&0x0F));
if(dReq.bRequest==CLEAR_FEATURE) // clear endpoint stall (limit to 7 IN's data endpoint)
Slave_inEPstall &= ~(0x01<<((dReq.wIndex>>8)&0x0F));
}
else // for OUT direction endpoint
{
if(dReq.bRequest==SET_FEATURE) // set endpoint stall (limit to 7 OUT's data endpoint)
Slave_outEPstall |= (0x01<<((dReq.wIndex>>8)&0x0F));
if(dReq.bRequest==CLEAR_FEATURE) // clear endpoint stall (limit to 7 OUT's data endpoint)
Slave_outEPstall &= ~(0x01<<((dReq.wIndex>>8)&0x0F));
}
EP0A_IN_Arm(0,0,1); // IN status stage
}
else
USBWrite(EP0AControl,SEND_STALL); // Stall unsupported requests
break;
default:
uartpush("__________default!\n\r");
USBWrite(EP0AControl,SEND_STALL); // Stall all unsupported requests
break;
}
break;
case SET_ADDRESS:
uartpush("____设置地址!\n\r");
Slave_USBaddr = dReq.wValue>>8; // update new USB address assigned by host
ltoa(Slave_USBaddr,data,16);
uartpush("####Slave_USBaddr=0x");
uartpush(data);
uartpush("\n\r");
EP0A_IN_Arm(0,0,1); // IN status stage
break;
case SET_CONFIG:
uartpush("____设置配置!\n\r");
Slave_ConfigVal = dReq.wValue>>8; // update configuration value
ltoa(Slave_ConfigVal,data,16);
uartpush("####Slave_ConfigVal=0x");
uartpush(data);
uartpush("\n\r");
EP0A_IN_Arm(0,0,1); // IN status stage
if(Slave_ConfigVal)
USBWrite(EP1AControl,DATA0_IN_ENABLE); // Enable EP1 (reponse with NAK)
else
USBWrite(EP1AControl,DATA0_IN_DISABLE); // Disable EP1
if(Slave_ConfigVal)
USBWrite(EP2AControl,DATA0_OUT_ENABLE); // Enable EP2 (reponse with NAK)
else
USBWrite(EP2AControl,DATA0_OUT_DISABLE); // Disable EP2
enum_done = 1; // end of complete enumeration
uartpush("_____enumeration may be done!\n\r");
break;
case SET_INTERFACE: // update alternate setting for
uartpush("____设置接口!\n\r");
Slave_IfcAlt[dReq.wIndex>>8] = dReq.wValue>>8; // selected interface number
ltoa(Slave_IfcAlt[dReq.wIndex>>8],data,16);
uartpush("####Slave_IfcAlt[dReq.wIndex>>8]=0x");
uartpush(data);
uartpush("\n\r");
EP0A_IN_Arm(0,0,1); // IN status stage
break;
default:
uartpush("________default!\n\r");
USBWrite(EP0AControl,SEND_STALL); // Stall all unsupported requests
break;
}
break;
//---------------------------------------------------------------------
// Specific Class Requests (HID)
//---------------------------------------------------------------------
case CLASS_REQUEST:
// uartpush("______CLASS_REQUEST!\n\r");
switch (dReq.bRequest) // Parse bRequest
{
case GET_IDLE:
//uartpush("________GET_IDLE!\n\r");
uartpush("____GET_IDLE!\n\r");
USBWrite(EP0A_Slave_Buf,Slave_IdleRate); // load current idle rate value
EP0A_IN_Arm(EP0A_Slave_Buf,1,1); // send 1 byte data back to host
len_req = 0;
break;
case GET_PROTOCOL:
//uartpush("________GET_PROTOCOL!\n\r");
uartpush("____获取协议!\n\r");
USBWrite(EP0A_Slave_Buf,Slave_Protocol); // load current protocol state
EP0A_IN_Arm(EP0A_Slave_Buf,1,1); // send 1 byte data back to host
len_req = 0;
break;
case SET_IDLE:
//uartpush("________SET_IDLE!\n\r");
uartpush("____SET_IDLE!\n\r");
Slave_IdleRate = (B8)dReq.wValue; // update Idle Rate (upper byte of wValue)
ltoa(Slave_IdleRate,data,16);
uartpush("####Slave_IdleRate=0x");
uartpush(data);
uartpush("\n\r");
EP0A_IN_Arm(0,0,1); // IN status stage
break;
case SET_PROTOCOL:
//uartpush("________SET_PROTOCOL!\n\r");
uartpush("____设置协议!\n\r");
Slave_Protocol = dReq.wValue>>8; // update protocol value, 0=Boot, 1=report
ltoa(Slave_Protocol,data,16);
uartpush("####Slave_Protocol=0x");
uartpush(data);
uartpush("\n\r");
EP0A_IN_Arm(0,0,1); // IN status stage
break;
default:
uartpush("________default!\n\r");
USBWrite(EP0AControl,SEND_STALL); // Stall all unsupported requests
break;
}
break;
//---------------------------------------------------------------------
// Specific Vendor Requests
//---------------------------------------------------------------------
case VENDOR_REQUEST:
//uartpush("______VENDOR_REQUEST!\n\r");
uartpush("____VENDOR_REQUEST!\n\r");
USBWrite(EP0AControl,SEND_STALL); // Stall all unsupported requests
break;
//---------------------------------------------------------------------
// Unsupported Requests
//---------------------------------------------------------------------
default:
uartpush("______default!\n\r");
USBWrite(EP0AControl,SEND_STALL); // Stall all unsupported requests
break;
}
}
//================================================================
// IN/OUT token received from host
//================================================================
else
{
//uartpush("____IN/OUT token received!\n\r");
//---------------------------------
// IN's ACKed
//---------------------------------
if(USBRead(EP0AControl)&DIRECTION)
{
//uartpush("______IN's ACKed!\n\r");
if(dev_first==0) // happens on the first get device descp
{ // the host terminate IN transfer prematurely
//uartpush("________"); //dev_first=0\n\r");
len_req = 0; // (if EP0 maxpktsize is only 8 bytes)
dev_first = 1; // reset len_req, end with OUT status stage
}
//--------------------------------------
// Continue with next IN if needed
//--------------------------------------
if(len_req)
{
//uartpush("________ Continue with next IN if needed!\n\r");
data_seq = (((USBRead(EP0AControl)&DATAX)==0) ? 1:0); // toggle DATA sequence
len_xfr = (len_req>=EP0_LEN) ? EP0_LEN:(B8)len_req; // get transfer length for EP0
if(!IN_NULL) // point to correct buffer location
EP0A_IN_Arm(EP0A_Slave_Buf+in_buffer_idx, len_xfr, data_seq);
else
EP0A_IN_Arm(0,0,data_seq); // transfer zero Null packet
in_buffer_idx += len_xfr; // update buffer location
len_req -= len_xfr; // update remaining data length
if(len_req==0 && len_xfr==EP0_LEN && !IN_EXACT) // handles null packet of data length
{ // to host is multiple of EP0_LEN, and
len_req = 1; // only if host request more than this
IN_NULL = TRUE; // value of length, otherwise, the extra
} // null pkt is not require.
}
//--------------------------------------
// Arm Status Stage OUT or new SETUP
//--------------------------------------
else // Arm status OUT or next SETUP requests
{
/*uartpush("________Arm Status Stage OUT or new SETUP!\n\r");*/
EP0A_OUT_Arm(EP0_LEN); // i.e. end of IN status stage.
}
}
//---------------------------------
// OUT's ACKed
//---------------------------------
else
{
//uartpush("______OUT's ACKed!\n\r");
if(byte_rx==0) // zero data packet received
{
/*uartpush("________Zero data packet received!\n\r");*/
EP0A_OUT_Arm(EP0_LEN); // get ready for next SETUP token
if((B8)dReq.wValue == HID_REPORT) // end of a report descp, indicate
{
enum_done = 1; // end of complete enumeration
uartpush("__________enumeration done!\n\r");
}
}///////////////////////////////////////////////////////////////////////////////////////
else if(byte_rx==1)
{
UsbBuf_C=USBRead(EP0A_Slave_Buf); //get the data received!
rIOPDATA=UsbBuf_C&0xf0; //write the data to the led
EP0A_OUT_Arm(EP0_LEN); //get ready for next SETUP token
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -