📄 pe_usb.c
字号:
INT8U *u8UsbCmd;
INT8U u8index;
// First we must check if this is the first Cx 8 byte command after USB reset.
// If this is the first Cx 8 byte command, we can check USB High/Full speed right now.
if(!bOTGChirpFinish)
{
// first ep0 command after usb reset, means we can check usb speed right now.
bOTGChirpFinish = TRUE;
if(u8OTGMessageLevel & MESS_INFO)
{
if (mUsbOTGHighSpeedST())
printf("L%x: high speed mode\n", u8LineOTGCount ++);
else
printf("L%x: full speed mode\n", u8LineOTGCount ++);
}
if (mUsbOTGHighSpeedST()) // First we should judge HS or FS
{
bOTGHighSpeed = TRUE;
// Device stays in High Speed
// copy Device descriptors (from rom to sdram)
for (u8index = 0 ; u8index < sizeof(u8OTGHSDeviceDescriptor); u8index ++)
u8OTGDeviceDescriptorEX[u8index] = u8OTGHSDeviceDescriptor[u8index];
// copy Device Qualifierdescriptors (from rom to sdram)
// bLength
u8OTGDeviceQualifierDescriptorEX[0] = DEVICE_QUALIFIER_LENGTH;
// bDescriptorType Device_Qualifier
u8OTGDeviceQualifierDescriptorEX[1] = DT_DEVICE_QUALIFIER;
for (u8index = 2 ; u8index < 8; u8index ++)
u8OTGDeviceQualifierDescriptorEX[u8index] = u8OTGFSDeviceDescriptor[u8index];
// Number of Other-speed Configurations
u8OTGDeviceQualifierDescriptorEX[8] = u8OTGFSDeviceDescriptor[17];
//Reserved for future use, must be zero
u8OTGDeviceQualifierDescriptorEX[9] = 0x00;
// copy Config descriptors (from rom to sdram)
for (u8index = 0 ; u8index < sizeof(u8HSConfigOTGDescriptor01); u8index ++)
u8ConfigOTGDescriptorEX[u8index] = u8HSConfigOTGDescriptor01[u8index];
// copy Other speed Config descriptors (from rom to sdram)
for (u8index = 0 ; u8index < sizeof(u8FSConfigOTGDescriptor01); u8index ++)
u8OtherSpeedConfigOTGDescriptorEX[u8index] = u8FSConfigOTGDescriptor01[u8index];
// Change Descriptor type "DT_OTHER_SPEED_CONFIGURATION"
u8OtherSpeedConfigOTGDescriptorEX[1] = DT_OTHER_SPEED_CONFIGURATION;
}
else
{
bOTGHighSpeed = FALSE;
// Device stays in Full Speed
// copy Device descriptors (from rom to sram)
for (u8index = 0 ; u8index < sizeof(u8OTGFSDeviceDescriptor); u8index ++)
u8OTGDeviceDescriptorEX[u8index] = u8OTGFSDeviceDescriptor[u8index];
// copy Device Qualifierdescriptors (from rom to sram)
// bLength
u8OTGDeviceQualifierDescriptorEX[0] = DEVICE_QUALIFIER_LENGTH;
// bDescriptorType Device_Qualifier
u8OTGDeviceQualifierDescriptorEX[1] = DT_DEVICE_QUALIFIER;
for (u8index = 2 ; u8index < 8; u8index ++)
u8OTGDeviceQualifierDescriptorEX[u8index] = u8OTGHSDeviceDescriptor[u8index];
// Number of Other-speed Configurations
u8OTGDeviceQualifierDescriptorEX[8] = u8OTGHSDeviceDescriptor[17];
//Reserved for future use, must be zero
u8OTGDeviceQualifierDescriptorEX[9] = 0x00;
// copy Config descriptors (from rom to sram)
for (u8index = 0 ; u8index < sizeof(u8FSConfigOTGDescriptor01); u8index ++)
u8ConfigOTGDescriptorEX[u8index] = u8FSConfigOTGDescriptor01[u8index];
// copy Other speed Config descriptors (from rom to sram)
for (u8index = 0 ; u8index < sizeof(u8HSConfigOTGDescriptor01); u8index ++)
u8OtherSpeedConfigOTGDescriptorEX[u8index] = u8HSConfigOTGDescriptor01[u8index];
// Change Descriptor type "DT_OTHER_SPEED_CONFIGURATION"
u8OtherSpeedConfigOTGDescriptorEX[1] = DT_OTHER_SPEED_CONFIGURATION;
}
// copy String descriptors (from rom to sram)
for (u8index = 0 ; u8index < sizeof(u8OTGString00Descriptor); u8index ++)
u8OTGString00DescriptorEX[u8index] = u8OTGString00Descriptor[u8index];
for (u8index = 0 ; u8index < sizeof(u8OTGString10Descriptor); u8index ++)
u8OTGString10DescriptorEX[u8index] = u8OTGString10Descriptor[u8index];
for (u8index = 0 ; u8index < sizeof(u8OTGString20Descriptor); u8index ++)
u8OTGString20DescriptorEX[u8index] = u8OTGString20Descriptor[u8index];
for (u8index = 0 ; u8index < sizeof(u8OTGString30Descriptor); u8index ++)
u8OTGString30DescriptorEX[u8index] = u8OTGString30Descriptor[u8index];
for (u8index = 0 ; u8index < sizeof(u8OTGString40Descriptor); u8index ++)
u8OTGString40DescriptorEX[u8index] = u8OTGString40Descriptor[u8index];
for (u8index = 0 ; u8index < sizeof(u8OTGString50Descriptor); u8index ++)
u8OTGString50DescriptorEX[u8index] = u8OTGString50Descriptor[u8index];
}
u32UsbCmd = (INT32U*)malloc(8);
// Read 8-byte setup packet from FIFO
mUsbDMA2FIFOSel(FOTG200_DMA2CxFIFO);
u32UsbCmd[0] = mUsbEP0CmdDataRdDWord();
u32UsbCmd[1] = mUsbEP0CmdDataRdDWord();
mUsbDMA2FIFOSel(FOTG200_DMA2FIFO_Non);
u8UsbCmd = u32UsbCmd;
c = u8UsbCmd[0]; // get 1st byte
ControlOTGCmd.Direction = (unsigned char)(c & 0x80); // xfer Direction(IN, OUT)
ControlOTGCmd.Type = (unsigned char)(c & 0x60); // type(Standard, Class, Vendor)
ControlOTGCmd.Object = (unsigned char)(c & 0x03); // Device, Interface, Endpoint
ControlOTGCmd.Request = u8UsbCmd[1]; // get 2nd byte
ControlOTGCmd.Value = u8UsbCmd[2]; // get 3rd byte
c = u8UsbCmd[3]; // get 4th byte
ControlOTGCmd.Value |= (c<<8);
ControlOTGCmd.Index = u8UsbCmd[4]; // get 5th byte
c = u8UsbCmd[5]; // get 6th byte
ControlOTGCmd.Index |= (c<<8);
ControlOTGCmd.Length = u8UsbCmd[6]; // get 7th byte
c = u8UsbCmd[7]; // get 8th byte
ControlOTGCmd.Length |= (c<<8);
if(!(((u8UsbCmd[0] == 0x40)&&
(u8UsbCmd[1] == 0x00)&&
(u8UsbCmd[2] == 0x00)&&
(u8UsbCmd[3] == 0x00)&&
(u8UsbCmd[4] == 0x00)&&
(u8UsbCmd[5] == 0x00))||
((u8UsbCmd[0] == 0xC0)&&
(u8UsbCmd[1] == 0x00)&&
(u8UsbCmd[2] == 0x00)&&
(u8UsbCmd[3] == 0x00)&&
(u8UsbCmd[4] == 0x00)&&
(u8UsbCmd[5] == 0x00)))) // do not print test vendor command
{
if(u8OTGMessageLevel & MESS_INFO)
{
printf("L%x: EP0Cmd:", u8LineOTGCount ++);
for (c = 0; c < 0x08; c ++)
printf(" %02x", u8UsbCmd[c]);
printf("\n");
}
}
// Command Decode
if (ControlOTGCmd.Type == 0) // standard command
{
if (bOTGStandardCommand() == FALSE)
eOTGCxFinishAction = ACT_STALL;
}
else if ((ControlOTGCmd.Type & 0x60) >> 5 == 1) // class command
{
// ClassCommand();
eOTGCxFinishAction = ACT_STALL;
}
else if ((ControlOTGCmd.Type & 0x60) >> 5 == 2) // vendor command
{
// Vendor command test (for Cx OUT test)
// If we OUT Cx data as below, FOTG200 Device will wait for .
if((u8UsbCmd[0] == 0x40)&&
(u8UsbCmd[1] == 0x00)&&
(u8UsbCmd[2] == 0x00)&&
(u8UsbCmd[3] == 0x00)&&
(u8UsbCmd[4] == 0x00)&&
(u8UsbCmd[5] == 0x00))
{
vCxOUT_VendorTest();
}
else if((u8UsbCmd[0] == 0xC0)&&
(u8UsbCmd[1] == 0x00)&&
(u8UsbCmd[2] == 0x00)&&
(u8UsbCmd[3] == 0x00)&&
(u8UsbCmd[4] == 0x00)&&
(u8UsbCmd[5] == 0x00))
{
vCxIN_VendorTest();
vCxIN_VendorTxData();
}
else
{
eOTGCxFinishAction = ACT_STALL;
}
}
else
{
// Invalid(bad) command, Return EP0_STALL flag
eOTGCxFinishAction = ACT_STALL;
}
free(u32UsbCmd);
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_ep0tx()
// Description:
// 1. Transmit data to EP0 FIFO.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_ep0tx(void)
{
switch(eOTGCxCommand)
{
case CMD_GET_DESCRIPTOR:
vOTGEP0TxData();
break;
case CMD_CxIN_Vendor:
vCxIN_VendorTxData();
break;
default:
mUsbEP0StallSet();
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_ep0rx()
// Description:
// 1. Receive data from EP0 FIFO.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_ep0rx(void)
{
switch(eOTGCxCommand)
{
case CMD_SET_DESCRIPTOR:
vOTGEP0RxData();
break;
case CMD_CxOUT_Vendor:
vCxOUT_VendorRxData();
break;
default:
mUsbEP0StallSet();
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_ep0end()
// Description:
// 1. End this transfer.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_ep0end(void)
{
eOTGCxCommand = CMD_VOID;
mUsbEP0DoneSet(); // Return EP0_Done flag
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_ep0fail()
// Description:
// 1. Stall this transfer.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_ep0fail(void)
{
mUsbEP0StallSet(); // Return EP0_Stall
if(u8OTGMessageLevel & (MESS_ERROR | MESS_WARNING | MESS_INFO))
printf("L%x: EP0 fail\n", u8LineOTGCount ++);
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_ep0abort()
// Description:
// 1. Stall this transfer.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_ep0abort(void)
{
mUsbIntEP0AbortClr(); // Clean EP0 abort
if(u8OTGMessageLevel & (MESS_ERROR))
printf("L%x: EP0 command abort\n", u8LineOTGCount ++);
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_rst()
// Description:
// 1. Change descriptor table (High or Full speed).
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_rst(void)
{
mUsbDevAddrSet(0);
// Init AP
vOTG_APInit();
// start
#if (OTG_AP_Satus == Bulk_AP)
#if(Bulk_Satus == Bulk_FIFO_SingleDir)
mUsbIntF2OUTEn();
#elif(Bulk_Satus == Bulk_FIFO_BiDir)
mUsbIntF0OUTEn();
mUsbIntF2INEn();
mUsbIntF3OUTEn();
#endif
mUsbIntF0INDis();
#endif
#if 0
#if (OTG_AP_Satus == Interrupt_AP)
mUsbIntF0INEn();
#endif
#if (OTG_AP_Satus == IsochronousIN_AP)
mUsbIntF0INEn();
#endif
#endif
#if (OTG_AP_Satus == IsochronousOUT_AP)
mUsbIntF0OUTEn();
#endif
// stop
if(u8OTGMessageLevel & MESS_INFO)
{
printf("L%x: Bus reset\n", u8LineOTGCount ++);
}
mUsbIntBusRstClr();
mUsbClrAllFIFOSet();
//Bruce;;03152005 mUsbTstHalfSpeedEn();
bOTGChirpFinish = FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_suspend()
// Description:
// 1. Clear suspend interrupt, and set suspend register.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_suspend(void)
{
if(u8OTGMessageLevel & MESS_INFO)
printf("L%x: Bus suspend\n", u8LineOTGCount ++);
// We have already set USB suepend counter in vFOTG200_Dev_Init().
// Before enter into the suspend mode, we must finish all things about USB.
// And then USB device into Suspend mode.
mUsbIntSuspClr();
//Reserve for OTG;;mUsbGoSuspend();
}
///////////////////////////////////////////////////////////////////////////////
// vOTG_resm()
// Description:
// 1. Clear resume interrupt status and leave supend mode.
// input: none
// output: none
///////////////////////////////////////////////////////////////////////////////
void vOTG_resm(void)
{
if(u8OTGMessageLevel & MESS_INFO)
printf("L%x: Bus resume\n", u8LineOTGCount ++);
mUsbIntResmClr();
}
///////////////////////////////////////////////////////////////////////////////
// bOTGStandardCommand()
// Description:
// 1. Process standard Cx 8 bytes command.
// input: none
// output: TRUE or FALSE
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bOTGStandardCommand(void)
{
switch (ControlOTGCmd.Request) // by Standard Request codes
{
case 0: // get status
return (bGet_OTGstatus());
case 1: // clear feature
return (bClear_OTGfeature());
case 2: // Reserved for further use
break;
case 3: // set feature
return (bSet_OTGfeature());
case 4: // Reserved for further use
break;
case 5: // set address
if (!bOTGEP0HaltSt)
return(bSet_OTGaddress());
break;
case 6: // get descriptor
if (!bOTGEP0HaltSt)
return(bGet_OTGdescriptor());
break;
case 7: // set descriptor
if (!bOTGEP0HaltSt)
return(bSet_OTGdescriptor());
break;
case 8: // get configuration
if (!bOTGEP0HaltSt)
vGet_OTGconfiguration();
return TRUE;
case 9: // set configuration
if (!bOTGEP0HaltSt)
return(bSet_OTGconfiguration());
break;
case 10: // get interface
if (!bOTGEP0HaltSt)
return(bGet_OTGinterface());
break;
case 11: // set interface
if (!bOTGEP0HaltSt)
return(bSet_OTGinterface());
break;
case 12: // synch frame
if (!bOTGEP0HaltSt)
return(bSynch_OTGframe());
break;
default:
break;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// bGet_OTGstatus()
// Description:
// 1. Send 2 bytes status to host.
// input: none
// output: TRUE or FALSE (BOOLEAN)
///////////////////////////////////////////////////////////////////////////////
BOOLEAN bGet_OTGstatus(void)
{
INT8U u8ep_n;
INT8U u8fifo_n;
BOOLEAN bdir;
INT8U RecipientStatusLow, RecipientStatusHigh;
INT8U u8Tmp[2];
RecipientStatusLow = 0;
RecipientStatusHigh = 0;
switch (ControlOTGCmd.Object) // Judge which recipient type is at first
{
case 0: // Device
// Return 2-byte's Device status (Bit1:Remote_Wakeup, Bit0:Self_Powered) to Host
// Notice that the programe sequence of RecipientStatus
RecipientStatusLow = (mUsbRmWkupST() == 1)? BIT1: 0; //(((INT8U)mUsbRmWkupST()) << 1);
// Bit0: Self_Powered--> DescriptorTable[0x23], D6(Bit 6)
RecipientStatusLow |= ((u8ConfigOTGDescriptorEX[0x07] >> 6) & 0x01);
break;
case 1: // Interface
// Return 2-byte ZEROs Interface status to Host
break;
case 2: // Endpoint
if(ControlOTGCmd.Index == 0x00)
RecipientStatusLow = (INT8U)bOTGEP0HaltSt;
else
{
u8ep_n = ControlOTGCmd.Index & 0x7F; // which ep will be clear
bdir = ControlOTGCmd.Index >> 7; // the direction of this ep
if (u8ep_n > FOTG200_Periph_MAX_EP) // over the Max. ep count ?
return FALSE;
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -