📄 usb.c
字号:
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 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 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 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 DEVICE FEATURE
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
USB_REQ_SET_FEATURE,
FEATURE_REMOTE_WAKEUP,0x00, // feature selector
0x00,0x00,
0x00,0x00,
0xff,&usbSetRemoteWakeup, // df, setDeviceFeature
// 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,&usbClearRemoteWakeup,
// SET INTERFACE FEATURE
USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_SET_INTERFACE,
0xff,0x00, // alternative setting
0xff,0x00, // interface number
0x00,0x00,
0xd7,&usbSetInterface,
// END OF LIST CATCH-ALL REQUEST:
// This will match any USB request sicne bCompareMask is 0x00.
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,&usbNonStandardRequest
};
/***************************************************************************
* Function: UsbDecodeAndProcessUsbRequest() *
* Programmer: Lobo Tai (lobotai@ti.com) *
* Description: This function is called when a USB request has been *
* received. It searches the tUsbRequestList[] structure defined in *
* the previous section for a request that matches a given entry in *
* the table and, when matched, executes the corresponding function. *
***************************************************************************/
VOID usbDecodeAndProcessUsbRequest(VOID)
{
BYTE bMask,bResult,bTemp;
BYTE *pbUsbRequestList; // save code space
// We initialize the pbUsbRequestList pointer to the beginning of the
// tUsbRequestList[] so that we can subsequently traverse the table
// by incrementing the pbUsbRequestList pointer.
pbUsbRequestList = (PBYTE) &tUsbRequestList[0];
// Cycle indefinitely until we've found an entry in the tUsbRequestList[]
// table. Since the last entry in the table has a 0x00 mask, we'll
// *always* find a match, so this cycle will always exit.
while(1)
{
bResult = 0x00;
bMask = 0x80;
// We cycle through fields 0 through 7, which correspond to the 8 fields
// in each entry of tUsbRequestList. If the given byte in the packet
// we just receive is equal to the corresponding byte in the table, we
// set that bit in the result, indicating a byte which matched. Otherwise,
// we don't set the bit which means that byte didn't match.
for(bTemp = 0; bTemp < 8; bTemp++)
{
if(*(pbEP0_SETUP_ADDRESS+bTemp) == *(pbUsbRequestList+bTemp))
bResult |= bMask;
bMask = bMask >> 1;
}
// At this point, bResult holds 8 bits which indicate whether each of the
// bytes in the packet matched the corresponding bytes in the tUsbRequestList[]
// table. We then AND the mask value in the table with the result so that
// we only are comparing the bits required in the mask. If the resulting
// value is equal to the mask, that means that all significant bytes match.
// This is done since any bit that is clear in the mask is a "don't care", so
// the AND makes sure we don't reject a "valid" comparison beause a don't
// care bit actually matched.
if((*(pbUsbRequestList+bTemp) & bResult) == *(pbUsbRequestList+bTemp))
break;
// If we haven't found a matching entry yet, we advenced the pointer to point
// to the next entry in the table, and keep looking.
pbUsbRequestList += sizeof(tDEVICE_REQUEST_COMPARE);
}
// We check to see if any more setup packet(s) have been received and, if so, we
// anbandon this one to hanlde the next one.
if(bUSBSTA & (USBSTA_SETUP | USBSTA_STPOW) != 0x00)
return;
// If we've reached this point of the function, we've found the function that should
// be called given the current request. So we call it...
((ptDEVICE_REQUEST_COMPARE)pbUsbRequestList)->pUsbFunction();
}
/***************************************************************************
* Function: usbStallEndpoint0() *
* Programmer: Lobo Tai (lobotai@ti.com) *
* Description: Sets the STALL flag on both IEP0 and OEP0. Often called *
* to reflect an error condition. *
***************************************************************************/
void usbStallEndpoint0(void)
{
tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
}
/***************************************************************************
* Function: usbReceiveDataPacketOnEP0 / ReceiveNextPacket *
* Programmer: Lobo Tai (lobotai@ti.com) *
* Description: These two functions, together, are used to receive a data *
* payload on the OEP0 endpoint. The reception is first initiated by *
* calling usbReceiveDataPacketOnEP0 and indicating the address that the*
* received data should be placed in. As each data packet is received, *
* the usbReceiveNextPacketOnOEP0 will be called to process the packet *
* and determine if the packet received was the last packet, or if there*
* are more packets coming. *
***************************************************************************/
void usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
{
pbOEP0Buffer = pbBuffer;
wBytesRemainingOnOEP0 = (WORD)(tSetupPacket.bLengthH << 8) | (WORD)tSetupPacket.bLengthL;
bStatusAction = STATUS_ACTION_DATA_OUT;
usbClearOEP0ByteCount;
}
void usbReceiveNextPacketOnOEP0(void)
{
BYTE bIndex,bByte;
// First we must determine how many bytes were received in this data
// packet. We AND it with EPBCT_BYTECNT_MASK so that a NAK condition
// will return "0 bytes."
bByte = tEndPoint0DescriptorBlock.bOEPBCNT & EPBCT_BYTECNT_MASK;
// If the number of bytes remaining to be received is greater than
// or equal to the number of bytes received in this packet then
// we handle the packet. However, if we received more bytes than
// we had expected we simply ignore the packet since it is
// presumably erroneous.
if(wBytesRemainingOnOEP0 >= (WORD)bByte)
{
// For each of the bytes received, we copy the value received to the
// next position in the buffer we set aside for the OEP0 data.
for(bIndex=0;bIndex<bByte;bIndex++)
*pbOEP0Buffer++ = abOEP0Buffer[bIndex];
// We now reduce the number of bytes remaining by the number of bytes
// received in this packet.
wBytesRemainingOnOEP0 -= (WORD)bByte;
// If there are still more bytes to be received in additional packets (i.e.,
// wBytesRemainingOnOEP0 is greater than zero), we clear the byte count and
// reestablish bStatusAction to indicate that we are still in a DATA_OUT
// condition.
if(wBytesRemainingOnOEP0 > 0)
{
usbClearOEP0ByteCount;
bStatusAction = STATUS_ACTION_DATA_OUT;
}
else
{
// If we aren't expecting any more data bytes, we terminate the OEP0
// transaction by stalling OEP0 and setting the bStatusAction condition
// to "Nothing." Since in this firmware the only USB function that
// includes a subsequent data payload is the Set_Report function, we
// automatically update the keyboard LEDs with the new value. If
// additional features are added that expect data payloads, calling
// the OEP0SetLeds() function when a Set_Report request was not
// received will cause no harm.
usbStallOEP0;
bStatusAction = STATUS_ACTION_NOTHING;
OEP0SetLEDs();
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -