📄 usb.c
字号:
// fill true configuration group size
wTemp = sizeof(abromConfigurationDescriptorGroup);
abDescriptor[2] = wTemp;
abDescriptor[3] = wTemp>>8;
usbClearOEP0ByteCount();
wBytesRemainingOnIEP0 = sizeof(abromConfigurationDescriptorGroup);
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
}
#ifdef RAW_STRING_DESCRIPTOR
VOID usbGetStringDescriptor(VOID)
{
WORD bIndex;
usbClearOEP0ByteCount(); // for status stage
bIndex = 0x00;
while(tSetupPacket.bValueL-- > 0x00) bIndex += abromStringDescriptor[bIndex];
wBytesRemainingOnIEP0 = abromStringDescriptor[bIndex];
usbSendDataPacketOnEP0((PBYTE)&abromStringDescriptor[bIndex]);
}
#else
BYTE strlen(char *string)
{
BYTE str;
for(str = 0; str < 255 ; str++)
if( string[str] == 0x00 )
return(str);
return(0);
}
void usbGetStringDescriptor(void)
{
BYTE bTemp;
BYTE stringOffset = 0;
usbClearOEP0ByteCount();
switch(tSetupPacket.bValueL)
{
case 0: // LANGUAGE ID
abDescriptor[0] = 4; // Length of language descriptor ID
abDescriptor[1] = DESC_TYPE_STRING; // LANGID tag
abDescriptor[2] = 0x09; // Low byte of 0x0409 (English)
abDescriptor[3] = 0x04; // High byte of 0x0409 (English)
break;
case 1: // MANUFACTURER DESCRIPTION
abDescriptor[stringOffset++] = strlen(mfgDescription) * 2 + 2; // Length of this string
abDescriptor[stringOffset++] = DESC_TYPE_STRING; // String descriptor type
for(bTemp = 0; bTemp < strlen(mfgDescription);bTemp++)
{
abDescriptor[stringOffset++] = mfgDescription[bTemp]; // Insert the character from the string
abDescriptor[stringOffset++] = 0x00; // Insert a trailing 00h for Unicode representation
}
break;
case 2: // PRODUCT DESCRIPTION
abDescriptor[stringOffset++] = strlen(prodDescription) * 2 + 2; // Length of this string
abDescriptor[stringOffset++] = DESC_TYPE_STRING; // String descriptor type
for(bTemp = 0; bTemp < strlen(prodDescription);bTemp++)
{
abDescriptor[stringOffset++] = prodDescription[bTemp]; // Insert the character from the string
abDescriptor[stringOffset++] = 0x00; // Insert a trailing 00h for Unicode representation
}
break;
case 3: // SERIAL NUMBER
abDescriptor[stringOffset++] = strlen(serialNumber) * 2 + 2; // Length of this string
abDescriptor[stringOffset++] = DESC_TYPE_STRING; // String descriptor type
for(bTemp = 0; bTemp < strlen(serialNumber);bTemp++)
{
abDescriptor[stringOffset++] = serialNumber[bTemp]; // Insert the character from the string
abDescriptor[stringOffset++] = 0x00; // Insert a trailing 00h for Unicode representation
}
break;
default:
break;
}
wBytesRemainingOnIEP0 = abDescriptor[0];
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
}
#endif
//----------------------------------------------------------------------------
VOID usbGetInterface(VOID)
{
// not fully supported, return one byte, zero
usbClearOEP0ByteCount(); // for status stage
wBytesRemainingOnIEP0 = 0x01;
abUsbRequestReturnData[0] = bInterfaceNumber;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
}
//----------------------------------------------------------------------------
VOID usbGetDeviceStatus(VOID)
{
if((abromConfigurationDescriptorGroup[OFFSET_CONFIG_DESCRIPTOR_POWER] &
CFG_DESC_ATTR_SELF_POWERED) == CFG_DESC_ATTR_SELF_POWERED)
abUsbRequestReturnData[0] = DEVICE_STATUS_SELF_POWER;
// if((abromConfigurationDescriptorGroup[OFFSET_CONFIG_DESCRIPTOR_POWER] &
// CFG_DESC_ATTR_REMOTE_WAKE) == CFG_DESC_ATTR_REMOTE_WAKE)
// abUsbRequestReturnData[0] |= DEVICE_STATUS_REMOTE_WAKEUP;
if(bRemoteWakeup == ENABLE)
abUsbRequestReturnData[0] |= DEVICE_STATUS_REMOTE_WAKEUP;
usbClearOEP0ByteCount(); // for status stage
// Return self power status and remote wakeup status
wBytesRemainingOnIEP0 = 2;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
}
//----------------------------------------------------------------------------
VOID usbGetInterfaceStatus(VOID)
{
// check bIndexL for index number (not supported)
usbClearOEP0ByteCount(); // for status stage
// Return two zero bytes
wBytesRemainingOnIEP0 = 2;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
}
//----------------------------------------------------------------------------
VOID usbGetEndpointStatus(VOID)
{
BYTE bEndpointNumber;
// Endpoint number is bIndexL
bEndpointNumber = tSetupPacket.bIndexL & EP_DESC_ADDR_EP_NUM;
if(bEndpointNumber == 0x00){
if((tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN){
// input endpoint 0
abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bIEPCNFG & EPCNF_STALL);
}else{
// output endpoint 0
abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bOEPCNFG & EPCNF_STALL);
}
abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
usbClearOEP0ByteCount(); // for status stage
wBytesRemainingOnIEP0 = 0x02;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
}else{
bEndpointNumber--;
#ifdef BOOTCODE // bootcode only support output endpoint 1
if((bEndpointNumber == 0) && ((tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN) == 0x00)){
// output endpoint 1
abUsbRequestReturnData[0] = (BYTE)(tOutputEndPointDescriptorBlock[0].bEPCNF & EPCNF_STALL);
abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
usbClearOEP0ByteCount(); // for status stage
wBytesRemainingOnIEP0 = 0x02;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
}
#else
// EP is from EP1 to EP7 while C language start from 0
// Firmware should NOT response if specified endpoint is not supported. (charpter 8)
if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
if(tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN){
// input endpoint
abUsbRequestReturnData[0] = (BYTE)(tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
}else{
// output endpoint
abUsbRequestReturnData[0] = (BYTE)(tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
}
} // no response if endpoint is not supported.
abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
usbClearOEP0ByteCount();
wBytesRemainingOnIEP0 = 0x02;
usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
#endif
}
}
//----------------------------------------------------------------------------
VOID usbSetAddress(VOID)
{
usbStallOEP0(); // control write without data stage
// bValueL contains device address
if(tSetupPacket.bValueL < 128){
// hardware will update the address after status stage
// therefore, firmware can set the address now.
bFUNADR = tSetupPacket.bValueL;
usbSendZeroLengthPacketOnIEP0();
}else usbStallEndpoint0();
}
//----------------------------------------------------------------------------
VOID usbSetConfiguration(VOID)
{
usbStallOEP0(); // control write without data stage
// configuration number is in bValueL
// change the code if more than one configuration is supported
bConfigurationNumber = tSetupPacket.bValueL;
usbSendZeroLengthPacketOnIEP0();
}
/*
//----------------------------------------------------------------------------
VOID usbSetDeviceFeature(VOID)
{
// stall because bootcode does not support
usbStallEndpoint0();
// bValueL contains feature selector
// if(tSetupPacket.bValueL == FEATURE_REMOTE_WAKEUP){
// abConfigurationDescriptorGroup[OFFSET_CONFIG_DESCRIPTOR_POWER]
// |= CFG_DESC_ATTR_REMOTE_WAKE;
// usbSendZeroLengthPacketOnIEP0();
// }else usbStallEndpoint0();
}
*/
//----------------------------------------------------------------------------
VOID usbClearDeviceFeature(VOID)
{
// bValueL contains feature selector
if(tSetupPacket.bValueL == FEATURE_REMOTE_WAKEUP){
bRemoteWakeup = DISABLE;
bUSBMSK &= (USBMSK_WAKEUP^0xff);
usbSendZeroLengthPacketOnIEP0();
}else usbStallEndpoint0();
}
//----------------------------------------------------------------------------
VOID usbSetDeviceFeature(VOID)
{
// bValueL contains feature selector
if(tSetupPacket.bValueL == FEATURE_REMOTE_WAKEUP){
bRemoteWakeup = ENABLE;
usbSendZeroLengthPacketOnIEP0();
}else usbStallEndpoint0();
}
//----------------------------------------------------------------------------
VOID usbSetEndpointFeature(VOID)
{
BYTE bEndpointNumber;
usbStallOEP0(); // control write without data stage
// wValue contains feature selector
// bIndexL contains endpoint number
// Endpoint number is in low byte of wIndex
if(tSetupPacket.bValueL == FEATURE_ENDPOINT_STALL){
bEndpointNumber = tSetupPacket.bIndexL & EP_DESC_ADDR_EP_NUM;
if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0(); // do nothing for endpoint 0
else{
bEndpointNumber--;
#ifdef BOOTCODE
if((bEndpointNumber == 0x00) && ((tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN) == 0x00)){ // endpoint 1
// output endpoint 1
tOutputEndPointDescriptorBlock[0].bEPCNF |= EPCNF_STALL;
usbSendZeroLengthPacketOnIEP0();
} // no response if endpoint is not supported.
#else
// Firmware should NOT response if specified endpoint is not supported. (charpter 8)
if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
if(tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN){
// input endpoint
tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
}else{
// output endpoint
tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
}
usbSendZeroLengthPacketOnIEP0();
} // no response if endpoint is not supported.
#endif
}
}else usbStallEndpoint0();
}
//----------------------------------------------------------------------------
VOID usbSetInterface(VOID)
{
// bValueL contains alternative setting
// bIndexL contains interface number
// change code if more than one interface is supported
usbStallOEP0(); // control write without data stage
bInterfaceNumber = tSetupPacket.bIndexL;
usbSendZeroLengthPacketOnIEP0();
}
//----------------------------------------------------------------------------
VOID usbInvalidRequest(VOID)
{
// check if setup overwrite is set
// if set, do nothing since we might decode it wrong
// setup packet buffer could be modified by hardware if another setup packet
// was sent while we are deocding setup packet
if((bUSBSTA & USBSTA_STPOW) == 0x00) usbStallEndpoint0();
}
void usbGetHIDDescriptor(void)
{
//BYTE bTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
// for(bTemp=0;bTemp<SIZEOF_DEVICE_DESCRIPTOR;bTemp++)
// abDescriptor[bTemp] = abromConfigurationDescriptorGroup[SIZEOF_CONFIG_DESCRIPTOR+SIZEOF_INTERFACE_DESCRIPTOR + bTemp];
usbClearOEP0ByteCount();
wBytesRemainingOnIEP0 = SIZEOF_KEYBD_HID_DESCRIPTOR;
usbSendDataPacketOnEP0((PBYTE)&abromReportDescriptor);
}
void usbGetReportDescriptor(void)
{
usbClearOEP0ByteCount();
wBytesRemainingOnIEP0 = SIZEOF_REPORT_DESCRIPTOR;
usbSendDataPacketOnEP0((PBYTE)&abromReportDescriptor);
}
extern BYTE bLED;
void usbSetReport(void)
{
wBytesRemainingOnOEP0 = 1;
usbReceiveDataPacketOnEP0((PBYTE) &bLED);
}
BYTE gbIdleRateL;
BYTE gbIdleRateH;
void usbSetIdle(void)
{
// usbStallOEP0;
gbIdleRateL = tSetupPacket.bValueL;
gbIdleRateH = tSetupPacket.bValueH;
usbSendZeroLengthPacketOnIEP0();
}
void usbGetIdle(void)
{
wBytesRemainingOnIEP0 = 1;
usbSendDataPacketOnEP0(&gbIdleRateH);
}
BYTE gbProtocol=1; // default is report protocol
void usbSetProtocol(void)
{
// usbStallOEP0;
gbProtocol = tSetupPacket.bValueL;
usbSendZeroLengthPacketOnIEP0();
}
void usbGetProtocol(void)
{
wBytesRemainingOnIEP0 = 1;
usbSendDataPacketOnEP0(&gbProtocol);
}
//----------------------------------------------------------------------------
// Bit definitions for DEVICE_REQUEST.bmRequestType
// Bit 7: Data direction
// Bit 6-5: Type
// Bit 4-0: Recipient
// bmRequestType bRequest bValueL bValueH bIndexL bIndexH bLengthL bLengthH bCompareMask *fp
//----------------------------------------------------------------------------
code tDEVICE_REQUEST_COMPARE tUsbRequestList[] =
{
//
// the following listing are for vendor specific USB requests
//
// Vendor Specific Request
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_DBUS_T, // interface set dbus transmitter configurable parameters
0xff,0xff, // wValue(lsb): data[0], wValue(msb): data[3]
0x00,0x00, // interface number 0
0x00,0x00, // no data
0xcf,&usbVendorRequest,
// Vendor Specific Request
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_DBUS_R, // interface set dbus receiver configurable parameters
0xff,0xff, // wValue(lsb): data[1], wValue(msb): data[2]
0x00,0x00, // interface number 0
0x00,0x00, // no data
0xcf,&usbVendorRequest,
// Vendor Specific Request
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -