📄 usb.c
字号:
// WORD wTemp;
bFUNADR = 0x00; // no device address
bFunctionSuspended = FALSE;
// if download firmware's checksum is wrong, reboot
// bReboot = FALSE;
// disconnect from USB
bUSBCTL = 0x00;
// a flag the bootcode knows if it has loaded firmware from i2c
// bLoadFirmwareFromI2C = FALSE;
// copy descriptor to allocated address
// copy device and configuration descriptor to external memory
/*
for(bTemp=0;bTemp<SIZEOF_DEVICE_DESCRIPTOR;bTemp++){
abDeviceDescriptor[bTemp] = abromDeviceDescriptor[bTemp];
RESET_WATCHDOG;
}
for(bTemp=0;bTemp<SIZEOF_BOOTCODE_CONFIG_DESC_GROUP;bTemp++){
abConfigurationDescriptorGroup[bTemp] = abromConfigurationDescriptorGroup[bTemp];
RESET_WATCHDOG;
}
for(bTemp=0;bTemp<SIZEOF_BOOTCODE_STRING_DESC_GROUP;bTemp++){
abStringDescriptor[bTemp] = abromStringDescriptor[bTemp];
RESET_WATCHDOG;
}
*/
/*
#ifdef UMPDBG // test on UMP board
#else
// check if DEVVID, DEVPID, SERNUM contain pre-define values.
if((bDEVVIDH != 0xff) && (bDEVVIDL != 0xff) && (bDEVPIDH != 0xff) && (bDEVPIDL != 0xff)){
// update VID and PID
abDeviceDescriptor[8] = bDEVVIDL;
abDeviceDescriptor[9] = bDEVVIDH;
abDeviceDescriptor[10] = bDEVPIDL;
abDeviceDescriptor[11] = bDEVPIDH;
abDeviceDescriptor[12] = bDEVREVL;
abDeviceDescriptor[13] = bDEVREVH;
bTemp = abDeviceDescriptor[16]; // index number
// if index number is zero, that means it does not support serial number
if(bTemp != 0x00){
wTemp = 0x0000;
// try to find the string index
while(bTemp != 0x00){
wTemp += (WORD)abStringDescriptor[wTemp];
bTemp--;
}
if(wTemp != 0x0000){
wTemp +=2; // point to first letter
abStringDescriptor[wTemp] = GetBCD(bSERNUM7 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM7 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM6 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM6 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM5 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM5 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM4 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM4 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM3 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM3 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM2 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM2 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM1 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM1 & 0x0f);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM0 >> 4);
wTemp+=2;
abStringDescriptor[wTemp] = GetBCD(bSERNUM0 & 0x0f);
wTemp+=2;
}
}
}
#endif
#ifdef UMPDBG // test on UMP board
#define bHUBCNF1 (* (char xdata *)0xFFF7) // HUB Configuration-1 Register
#define bHUBCNF2 (* (char xdata *)0xFFF6) // HUB Configuration-2 Register
#define bHUBPIDL (* (char xdata *)0xFFF8) // HUB PID Low-byte Register
#define bHUBPIDH (* (char xdata *)0xFFF9) // HUB PID High-byte Register
#define bHUBVIDL (* (char xdata *)0xFFFA) // HUB VID Low-byte Register
#define bHUBVIDH (* (char xdata *)0xFFFB) // HUB VID High-byte Register
// enable port 6 and keep power switch setting
bHUBCNF1 = 0x55;
bHUBCNF2 = 0x10;
bHUBPIDL = 0x11;
bHUBPIDH = 0x22;
bHUBVIDL = 0x33;
bHUBVIDH = 0x44;
P1 = 0x55;
#endif
*/
// Disable endpoint 0 interrupt
tEndPoint0DescriptorBlock.bIEPCNFG = 0x00;
tEndPoint0DescriptorBlock.bOEPCNFG = 0x00;
// Disable output endpoint 1 interrupt
tOutputEndPointDescriptorBlock[0].bEPCNF = 0x00;
// reset
// UsbReset();
// Enable the USB-specific Interrupts; SETUP, and RESET
bUSBMSK = USBMSK_SETUP | USBMSK_RSTR | USBMSK_SUSP | USBMSK_RESR | USBMSK_WAKEUP;
}
/*----------------------------------------------------------------------------+
| General Subroutines |
+----------------------------------------------------------------------------*/
//----------------------------------------------------------------------------
VOID usbStallEndpoint0(VOID)
{
RESET_WATCHDOG;
tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
}
//----------------------------------------------------------------------------
VOID usbClearOEP0ByteCount(VOID)
{
RESET_WATCHDOG;
tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
}
//----------------------------------------------------------------------------
/*
VOID usbClearIEP0ByteCount(VOID)
{
tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
}
*/
//----------------------------------------------------------------------------
VOID usbStallOEP0(VOID)
{
// in standard USB request, there is not control write request with data stage
// control write, stall output endpoint 0
// wLength should be 0 in all cases
RESET_WATCHDOG;
tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
}
//----------------------------------------------------------------------------
VOID usbSendNextPacketOnIEP0(VOID)
{
BYTE bPacketSize,bIndex;
// First check if there are bytes remaining to be transferred
if(wBytesRemainingOnIEP0 != NO_MORE_DATA){
if(wBytesRemainingOnIEP0 > EP0_PACKET_SIZE){
// More bytes are remaining than will fit in one packet
// there will be More IN Stage
bPacketSize = EP0_PACKET_SIZE;
wBytesRemainingOnIEP0 -= EP0_PACKET_SIZE;
bStatusAction = STATUS_ACTION_DATA_IN;
}else if (wBytesRemainingOnIEP0 < EP0_PACKET_SIZE){
// The remaining data will fit in one packet.
// This case will properly handle wBytesRemainingOnIEP0 == 0
bPacketSize = (BYTE)wBytesRemainingOnIEP0;
wBytesRemainingOnIEP0 = NO_MORE_DATA; // No more data need to be Txed
bStatusAction = STATUS_ACTION_NOTHING;
}else{
// wBytesRemainingOnIEP0 == EP0_PACKET_SIZE
bPacketSize = EP0_PACKET_SIZE;
if(bHostAskMoreDataThanAvailable == TRUE){
wBytesRemainingOnIEP0 = 0;
bStatusAction = STATUS_ACTION_DATA_IN;
}else{
wBytesRemainingOnIEP0 = NO_MORE_DATA;
bStatusAction = STATUS_ACTION_NOTHING;
}
}
RESET_WATCHDOG;
for(bIndex=0; bIndex<bPacketSize; bIndex++)
abIEP0Buffer[bIndex] = *pbIEP0Buffer++;
tEndPoint0DescriptorBlock.bIEPBCNT = bPacketSize; // & EPBCT_BYTECNT_MASK;
}else bStatusAction = STATUS_ACTION_NOTHING;
RESET_WATCHDOG;
}
//----------------------------------------------------------------------------
VOID usbSendDataPacketOnEP0(PBYTE pbBuffer)
{
WORD wTemp;
pbIEP0Buffer = pbBuffer;
wTemp = (WORD)(tSetupPacket.bLengthH << 8) | (WORD)tSetupPacket.bLengthL;
// Limit transfer size to wLength if needed
// this prevent USB device sending 'more than require' data back to host
if(wBytesRemainingOnIEP0 >= wTemp){
wBytesRemainingOnIEP0 = wTemp;
bHostAskMoreDataThanAvailable = FALSE;
}else bHostAskMoreDataThanAvailable = TRUE;
usbSendNextPacketOnIEP0();
}
//----------------------------------------------------------------------------
VOID usbReceiveNextPacketOnOEP0(VOID)
{
usbStallOEP0();
// bootcode does not use this.
/* BYTE bIndex,bByte;
bByte = tEndPoint0DescriptorBlock.bOEPBCNT & EPBCT_BYTECNT_MASK;
if(wBytesRemainingOnOEP0 >= (WORD)bByte){
for(bIndex=0;bIndex<bByte;bIndex++)
*pbOEP0Buffer++ = abOEP0Buffer[bIndex];
wBytesRemainingOnOEP0 -= (WORD)bByte;
// clear the NAK bit for next packet
if(wBytesRemainingOnOEP0 > 0){
usbClearOEP0ByteCount();
bStatusAction = STATUS_ACTION_DATA_OUT;
}else{
usbStallOEP0();
bStatusAction = STATUS_ACTION_NOTHING;
}
}else{
usbStallOEP0();
bStatusAction = STATUS_ACTION_NOTHING;
}
*/
}
//----------------------------------------------------------------------------
VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
{
pbOEP0Buffer = pbBuffer;
wBytesRemainingOnOEP0 =
(WORD)(tSetupPacket.bLengthH << 8) | (WORD)tSetupPacket.bLengthL;
bStatusAction = STATUS_ACTION_DATA_OUT;
usbClearOEP0ByteCount();
}
//----------------------------------------------------------------------------
VOID usbSendZeroLengthPacketOnIEP0(VOID)
{
RESET_WATCHDOG;
wBytesRemainingOnIEP0 = NO_MORE_DATA;
bStatusAction = STATUS_ACTION_NOTHING;
tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
}
//----------------------------------------------------------------------------
VOID usbClearEndpointFeature(VOID)
{
BYTE bEndpointNumber;
PUTS("CL");
// EP is from EP1 to EP7 while C language start from 0
bEndpointNumber = (tSetupPacket.bIndexL & EP_DESC_ADDR_EP_NUM);
if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();
else{
bEndpointNumber--;
#ifdef BOOTCODE
// check if it is output endpoint 1
// if other endpoints, ignore
if((bEndpointNumber == 0) && ((tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN) == 0x00)){
// output endpoint
tOutputEndPointDescriptorBlock[0].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGLE);
usbSendZeroLengthPacketOnIEP0();
}
#else
if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
if((tSetupPacket.bIndexL & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN){
// input endpoint
tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGLE);
}else{
// output endpoint
tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGLE);
}
usbSendZeroLengthPacketOnIEP0();
}
#endif
}
RESET_WATCHDOG;
}
//----------------------------------------------------------------------------
VOID usbGetConfiguration(VOID)
{
usbClearOEP0ByteCount(); // for status stage
wBytesRemainingOnIEP0 = 1;
usbSendDataPacketOnEP0((PBYTE)&bConfigurationNumber);
}
//----------------------------------------------------------------------------
//VOID usbSendDeviceDescriptor(VOID)
//{
// wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
// usbClearOEP0ByteCount(); // for status stage
// usbSendDataPacketOnEP0((PBYTE)&abDeviceDescriptor);
//
//}
//----------------------------------------------------------------------------
//VOID usbGetDeviceDescriptor(VOID)
//{
/*
// this prevent that correct firmware is downloaded and get more than
// two setups from host
if((bLoadFirmwareFromI2C == FALSE) && (bCurrentDataType == DATA_TYPE_HEADER_BINARY_FIRMWARE)){
bLoadFirmwareFromI2C = TRUE;
if(LoadBinaryFirmwareFromI2c() == NO_ERROR) bExecuteFirmware = TRUE;
else usbSendDeviceDescriptor();
}else if(bExecuteFirmware != TRUE) usbSendDeviceDescriptor(); // for request at second time
*/
// usbSendDeviceDescriptor();
//}
void usbGetDeviceDescriptor(void)
{
BYTE bTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
for(bTemp=0;bTemp<SIZEOF_DEVICE_DESCRIPTOR;bTemp++)
abDescriptor[bTemp] = abromDeviceDescriptor[bTemp];
usbClearOEP0ByteCount();
wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
usbSendDataPacketOnEP0((PBYTE)&abDescriptor);
}
/*
//----------------------------------------------------------------------------
VOID usbGetConfigurationDescriptor(VOID)
{
usbClearOEP0ByteCount(); // for status stage
wBytesRemainingOnIEP0 = SIZEOF_BOOTCODE_CONFIG_DESC_GROUP;
usbSendDataPacketOnEP0((PBYTE)&abConfigurationDescriptorGroup);
}
//----------------------------------------------------------------------------
VOID usbGetStringDescriptor(VOID)
{
WORD bIndex;
usbClearOEP0ByteCount(); // for status stage
bIndex = 0x00;
while(tSetupPacket.bValueL-- > 0x00) bIndex += abStringDescriptor[bIndex];
wBytesRemainingOnIEP0 = abStringDescriptor[bIndex];
usbSendDataPacketOnEP0((PBYTE)&abStringDescriptor[bIndex]);
}
*/
void usbGetConfigurationDescriptor(void)
{
BYTE bTemp;
WORD wTemp;
// Copy the DEVICE DESCRIPTOR from program "ROM" to XRAM
for(bTemp=0;bTemp<sizeof(abromConfigurationDescriptorGroup);bTemp++)
abDescriptor[bTemp] = abromConfigurationDescriptorGroup[bTemp];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -