📄 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 { u8fifo_n = mUsbEPMapRd(u8ep_n); // get the relatived FIFO number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -