📄 usb.c
字号:
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_DBUS, // interface return dbus configurable parameters
0x00,0x00, // wValue
0x00,0x00, // interface number 0
0x04,0x00, // 4 bytes data
0xff,&usbVendorRequest,
//
// the following listing are for standard USB requests
//
// clear device feature
// USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
// USB_REQ_CLEAR_FEATURE,
// FEATURE_REMOTE_WAKEUP,0x00,
// 0x00,0x00,
// 0x00,0x00,
// 0xff,&usbStallEndpoint0,
// clear interface feature
// USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
// USB_REQ_CLEAR_FEATURE,
// 0xff,0x00,
// 0xff,0x00,
// 0x00,0x00,
// 0xe7,&usbStallEndpoint0,
// clear device feature
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_CLEAR_FEATURE,
FEATURE_REMOTE_WAKEUP,0x00, // feature selector
0x00,0x00,
0x00,0x00,
0xff,&usbClearDeviceFeature,
// clear endpoint feature
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
USB_REQ_CLEAR_FEATURE,
FEATURE_ENDPOINT_STALL,0x00,
0xff,0x00,
0x00,0x00,
0xf7,&usbClearEndpointFeature,
// get configuration
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_GET_CONFIGURATION,
0x00,0x00,
0x00,0x00,
0x01,0x00,
0xff,&usbGetConfiguration,
// get device descriptor
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_GET_DESCRIPTOR,
0xff,DESC_TYPE_DEVICE, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xd0,&usbGetDeviceDescriptor,
// get configuration descriptor
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_GET_DESCRIPTOR,
0xff,DESC_TYPE_CONFIG, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xd0,&usbGetConfigurationDescriptor,
// get string descriptor
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_GET_DESCRIPTOR,
0xff,DESC_TYPE_STRING, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xd0,&usbGetStringDescriptor,
// GET HID DESCRIPTOR
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_DESCRIPTOR,
0xff,DESC_TYPE_HID, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xd0,&usbGetHIDDescriptor,
// GET REPORT DESCRIPTOR
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_DESCRIPTOR,
0xff,DESC_TYPE_REPORT, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xd0,&usbGetReportDescriptor,
// SET REPORT
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_REPORT,
0xff,0xFF, // bValueL is index and bValueH is type
0xff,0xff,
0xff,0xff,
0xC0,&usbSetReport,
// SET IDLE
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_IDLE,
0xff,0xFF, // bValueL is index and bValueH is type
0xff,0xff,
0x00,0x00,
0xc3,&usbSetIdle,
// SET PROTOCOL
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_PROTOCOL,
0xff,0xFF, // bValueL is index and bValueH is type
0xff,0xff,
0x00,0x00,
0xc3,&usbSetProtocol,
// GET IDLE
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_IDLE,
0xff,0xFF, // bValueL is index and bValueH is type
0xff,0xff,
0x01,0x00,
0xc3,&usbGetIdle,
// GET PROTOCOL
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_PROTOCOL,
0xff,0xFF, // bValueL is index and bValueH is type
0xff,0xff,
0x01,0x00,
0xc3,&usbGetProtocol,
// get interface
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_INTERFACE,
0x00,0x00,
0xff,0xff,
0x01,0x00,
0xf3,&usbGetInterface,
// get device status
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_GET_STATUS,
0x00,0x00,
0x00,0x00,
0x02,0x00,
0xff,&usbGetDeviceStatus,
// get interface status
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_GET_STATUS,
0x00,0x00,
0xff,0x00,
0x02,0x00,
0xf7,&usbGetInterfaceStatus,
// get endpoint status
USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
USB_REQ_GET_STATUS,
0x00,0x00,
0xff,0x00,
0x02,0x00,
0xf7,&usbGetEndpointStatus,
// set address
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_SET_ADDRESS,
0xff,0x00,
0x00,0x00,
0x00,0x00,
0xdf,&usbSetAddress,
// set configuration
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_SET_CONFIGURATION,
0xff,0x00,
0x00,0x00,
0x00,0x00,
0xdf,&usbSetConfiguration,
// set descriptor (Bootcode stalls to this request)
// USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
// USB_REQ_SET_DESCRIPTOR,
// 0xff,0xff, // descriptor type and descriptor index
// 0xff,0xff, // language ID
// 0xff,0xff, // desciprotr length
// 0xc0,&usbStallEndpoint0,
// set device feature
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_SET_FEATURE,
0xff,0x00, // feature selector
0x00,0x00,
0x00,0x00,
0xdf,&usbSetDeviceFeature,
// set interface feature
// USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
// USB_REQ_SET_FEATURE,
// 0xff,0x00,
// 0xff,0x00,
// 0x00,0x00,
// 0xd7,&usbStallEndpoint0,
// set endpoint feature
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
USB_REQ_SET_FEATURE,
0xff,0x00, // feature selector
0xff,0x00, // endpoint number <= 127
0x00,0x00,
0xd7,&usbSetEndpointFeature,
// set interface
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_INTERFACE,
0xff,0x00, // feature selector
0xff,0x00, // interface number
0x00,0x00,
0xd7,&usbSetInterface,
// synch frame (Bootcode stalls to this request)
// USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
// USB_REQ_SYNCH_FRAME,
// 0x00,0x00,
// 0xff,0x00, // endpoint number
// 0x02,0x00,
// 0xf7,&usbStallEndpoint0,
//
// end of usb descriptor -- this one will be matched to any USB request
// since bCompareMask is 0x00.
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,&usbInvalidRequest // end of list
};
//----------------------------------------------------------------------------
// This routine decode the setup packet and call perper routine
//typedef struct _tDEVICE_REQUEST_COMPARE
//{
// BYTE bmRequestType; // See bit definitions below
// BYTE bRequest; // See value definitions below
// BYTE bValueL; // Meaning varies with request type
// BYTE bValueH; // Meaning varies with request type
// BYTE bIndexL; // Meaning varies with request type
// BYTE bIndexH; // Meaning varies with request type
// BYTE bLengthL; // Number of bytes of data to transfer (LSByte)
// BYTE bLengthH; // Number of bytes of data to transfer (MSByte)
// BYTE bCompareMask; // MSB is bRequest, if set 1, bRequest should be matched
// VOID (*pUsbFunction)(VOID); // function pointer
//} tDEVICE_REQUEST_COMPARE, *ptDEVICE_REQUEST_COMPARE;
//
VOID usbDecodeAndProcessUsbRequest(VOID)
{
BYTE bMask,bResult,bTemp;
BYTE *pbUsbRequestList,abSetupPacketBuffer[8];
BYTE bRequestType,bRequest;
// the following routine takes very long time in simulation
// pbUsbRequestList = (PBYTE)&tUsbRequestList[0];
// while(1){
// bResult = 0x00;
// bMask = 0x80;
// // compare all the fields first
// for(bTemp = 0; bTemp < 8; bTemp++){
// if(*(pbEP0_SETUP_ADDRESS+bTemp) == *(pbUsbRequestList+bTemp)) bResult |= bMask;
// bMask = bMask >> 1;
// }
// // now we have the result
// if((*(pbUsbRequestList+bTemp) & bResult) == *(pbUsbRequestList+bTemp)) break;
// // advance to next one
// pbUsbRequestList += sizeof(tDEVICE_REQUEST_COMPARE);
// }
// copy setup packet to idata to speed up decoding
for(bTemp = 0; bTemp < 8; bTemp++)
abSetupPacketBuffer[bTemp] = *(pbEP0_SETUP_ADDRESS+bTemp);
// point to beginning of the matrix
pbUsbRequestList = (PBYTE)&tUsbRequestList[0];
while(1){
bRequestType = *pbUsbRequestList++;
bRequest = *pbUsbRequestList++;
RESET_WATCHDOG;
if(((bRequestType == 0xff) && (bRequest == 0xff)) ||
(abSetupPacketBuffer[0] == (USB_REQ_TYPE_INPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) ||
(abSetupPacketBuffer[0] == (USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) ){
pbUsbRequestList -= 2;
break;
}
if((bRequestType == abSetupPacketBuffer[0]) && (bRequest == abSetupPacketBuffer[1])){
// compare the first two
bResult = 0xc0;
bMask = 0x20;
// first two bytes matched, compare the rest
for(bTemp = 2; bTemp < 8; bTemp++){
if(abSetupPacketBuffer[bTemp] == *pbUsbRequestList++) bResult |= bMask;
bMask = bMask >> 1;
}
// now we have the result
if((*pbUsbRequestList & bResult) == *pbUsbRequestList){
pbUsbRequestList -= 8;
break;
}else pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-8);
}else pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-2);
}
// if another setup packet comes before we have the chance to process current
// setup request, we return here without processing the request
// this check is not necessary but still kept here to reduce response(or simulation) time
if((bUSBSTA & USBSTA_STPOW) != 0x00) return;
// now we found the match and jump to the function accordingly.
((ptDEVICE_REQUEST_COMPARE)pbUsbRequestList)->pUsbFunction();
}
/*----------------------------------------------------------------------------+
| Interrupt Sub-routines |
+----------------------------------------------------------------------------*/
//----------------------------------------------------------------------------
VOID SetupPacketInterruptHandler(VOID)
{
BYTE bTemp;
// NAK both input and output endpoints
tEndPoint0DescriptorBlock.bIEPBCNT = EPBCT_NAK;
tEndPoint0DescriptorBlock.bOEPBCNT = EPBCT_NAK;
usbProcessNewSetupPacket:
bUSBCTL |= USBCTL_SIR;
// copy the MSB of bmRequestType to DIR bit of USBCTL
if((tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT) == USB_REQ_TYPE_INPUT)
bUSBCTL |= USBCTL_DIR;
else bUSBCTL &= ~USBCTL_DIR;
bStatusAction = STATUS_ACTION_NOTHING;
// clear out return data buffer
for(bTemp=0;bTemp<USB_RETURN_DATA_LENGTH;bTemp++) abUsbRequestReturnData[bTemp] = 0x00;
// decode and process the request
usbDecodeAndProcessUsbRequest();
// check if there is another setup packet pending
// if it is, abadon current one by NAKing both data endpoint 0
if((bUSBSTA & USBSTA_STPOW) != 0x00){
bUSBSTA = USBSTA_STPOW;
goto usbProcessNewSetupPacket;
}
}
//----------------------------------------------------------------------------
VOID IEP0InterruptHandler(VOID)
{
tEndPoint0DescriptorBlock.bOEPBCNT = 0x00; // will be set by the hardware
if(bStatusAction == STATUS_ACTION_DATA_IN) usbSendNextPacketOnIEP0();
else tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL; // no more data
}
//----------------------------------------------------------------------------
VOID OEP0InterruptHandler(VOID)
{
tEndPoint0DescriptorBlock.bIEPBCNT = 0x00; // will be set by the hardware
if(bStatusAction == STATUS_ACTION_DATA_OUT) usbReceiveNextPacketOnOEP0();
else tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL; // no more data
}
/*----------------------------------------------------------------------------+
| Main Routine |
+----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------+
| End of source file |
+----------------------------------------------------------------------------*/
/*------------------------ Nothing Below This Line --------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -