📄 usbrx.c
字号:
void HandleGetDescriptor(void){ switch (_gUsbOtgDevReq[3]) { case 0x01: // device descriptor HandleGetDeviceDscptr(); break; case 0x02: // configuration descriptor HandleGetConfigDscptr(); break; case 0x03: // string descriptor HandleGetStringDscptr(); break; } //check for EP0 IN transfer done while (!(*(VP_U32)OTG_FUNC_EP_DSTAT & EP0IN)); //clear EP0 IN transfer done *(VP_U32)OTG_FUNC_EP_DSTAT = EP0IN; ClearXYBufferInt(); //un ready the EP0IN unready_ep_in(EP0); //to complete the status stage of Setup EP0Out_StatusStageTransferDone();}void HandleSetConfiguration(void){ //EPConfig for EP0 IN //DW0 = 0x00080000 configure EP0 for CTRL setup //DW1 = 0x00000020 //DW2 reserved //DW3 = 0x00E00000 TotalByteCnt = 0 byte EPConfig(EP0, EP_IN_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 8, 0); Enable_EP(1); // need to manually toggle because this is EP0 IN, previous transactions is EP0 SETUP (Out) // as this is the first transfer of EP0 IN, it suppose to DATA0 seq bit // but since this is a CTRL transfer, SETUP (EP0 OUT) follow by STATUS (EP0 IN) // thus although first transfer, it need to send DATA1, thus need to be manually toggle WriteEPToggleBit(EP0, EP_IN_DIR ,1); //Toggle Status Stage In PID from DATA0 to DATA1 //send IN with Empty packet to complete the status stage //set xfill to indicate data memory filled of EP0 IN *(VP_U32)OTG_FUNC_XFILL_STAT = EP0IN; ClearXYBufferInt(); Ready_EP_IN(0); //ready EP0 //send IN with Empty packet to complete the status stage //set xfill to indicate data memory filled of EP0 IN //*(VP_U32)OTG_FUNC_XFILL_STAT = EP0IN; //check for EP0 IN transfer done to send the Empty packet while (!(*(VP_U32)OTG_FUNC_EP_DSTAT & EP0IN)); //clear EP0 IN transfer done *(VP_U32)OTG_FUNC_EP_DSTAT = EP0IN; ClearXYBufferInt(); //un ready the EP0IN unready_ep_in(EP0);}void HandleGetDeviceDscptr(void){ int k=0; U32 EpStartAddress=0; //return all 18 bytes in data stage if (_gUsbOtgDevReq[6] == 0x12) { //Re - EPConfig for EP0 IN //DW0 = 0x00080000 configure EP0 for CTRL setup, max. ps = 8 //DW1 = 0x01000000 YBuf = 0x0000; XBuf = 0x00 //DW2 reserved //DW3 = 0x00E00012 buffer size = 17+1 ; TotalByteCnt = 18 byte // endpt dir stall se MPS format xbsa ybsa bufsize totalbytes // Disable_EP_IN(EP0); //disable EP0 IN EPConfig(EP0, EP_IN_DIR, 0, 0, 8, CTL_TYPE, (0*16), 200, 24, 18); // Enable_EP(1); // need to manually toggle because this is EP0 IN, previous transactions is EP0 SETUP (Out) // as this is the first transfer of EP0 IN, it suppose to DATA0 seq bit // but since this is a CTRL transfer, SETUP (EP0 OUT) follow by STATUS (EP0 IN) // thus although first transfer, it need to send DATA1, thus need to be manually toggle WriteEPToggleBit(EP0, EP_IN_DIR ,1); //Toggle Status Stage In PID from DATA0 to DATA1 //read the Start Address (xbsa, ybsa) if (EpNextBufToService & (EP0IN)) //X Buffer EpStartAddress = ((*(VP_U32)(OTG_EP_BASE+(16*1)+4))&0x0000FFFF); else //Y Buffer EpStartAddress = (((*(VP_U32)(OTG_EP_BASE+(16*1)+4))>>16)&0x0000FFFF); //write the 16 bytes data to the XBuff for (k=0;k<4;k++) *(VP_U32)(OTG_DATA_BASE +EpStartAddress + (k*0x4)) = _gUsbOtgDevDscptr[k] ; //write the last 2 bytes *(VP_U32)(OTG_DATA_BASE +EpStartAddress + (k*0x4)) = (_gUsbOtgDevDscptr[k] & 0xFFFF); ClearXYBufferInt(); Ready_EP_IN(0); //ready EP0 //Set/Clear Fill Status SetClearFillStatus(EP0IN); } //return just 8 bytes else { //Re - EPConfig for EP0 IN //DW0 = 0x00080000 configure EP0 for CTRL setup, max. ps = 8 //DW1 = 0x01000000 YBuf = 0x0100; XBuf = 0x00 //DW2 reserved //DW3 = 0x00E00008 buffer size = 7 +1 ; TotalByteCnt = 8 byte // Disable_EP_IN(EP0); //disable EP0 IN EPConfig(EP0, EP_IN_DIR, 0, 0, 8, CTL_TYPE, (0*16), 200, 8, 8); // Enable_EP(1); // need to manually toggle because this is EP0 IN, previous transactions is EP0 SETUP (Out) // as this is the first transfer of EP0 IN, it suppose to DATA0 seq bit // but since this is a CTRL transfer, SETUP (EP0 OUT) follow by STATUS (EP0 IN) // thus although first transfer, it need to send DATA1, thus need to be manually toggle WriteEPToggleBit(EP0, EP_IN_DIR ,1); //Toggle Status Stage In PID from DATA0 to DATA1 //read the Start Address (xbsa, ybsa) if (EpNextBufToService & (EP0IN)) //X Buffer EpStartAddress = ((*(VP_U32)(OTG_EP_BASE+(16*1)+4))&0x0000FFFF); else //Y Buffer EpStartAddress = (((*(VP_U32)(OTG_EP_BASE+(16*1)+4))>>16)&0x0000FFFF); //write the 8 bytes data to the XBuff for (k=0;k<2;k++) *(VP_U32)(OTG_DATA_BASE +EpStartAddress + (k*0x4)) = _gUsbOtgDevDscptr[k] ; ClearXYBufferInt(); Ready_EP_IN(0); //ready EP0 //Set/Clear Fill Status SetClearFillStatus(EP0IN); }}//***********************************************// Configure the PLL, GPIO and AHB//***********************************************void USBInit(){ //Do nothing. }inline void UsbotgSystemConfig(void){ // turn on the USBOTG clock ipg_clk_c *(VP_U32)CRM_PCCR0 |= 0x11004000; // configure GPIO for IUSBOTG uses *(VP_U32)GPIOB_GIUS = 0x003FFFFF; *(VP_U32)GPIOC_GIUS = 0xFFFFC01F; *(VP_U32)GPIOC_OCR2 = 0x0000AAAA; *(VP_U32)GPIOC_ICONFB2 = 0xFF00FFFF; *(VP_U32)GPIOC_DDIR = 0x00FF0000; *(VP_U32)GPIOD_GIUS = 0xFFFFFFFF; *(VP_U32)GPIOD_OCR2 = 0x00000000; *(VP_U32)GPIOD_ICONFA2 = 0xFFFFFC3F; *(VP_U32)GPIOD_DDIR = 0x01E00000; // configure tahiti chip access to AHB slave 3 (EMI) *(VP_U32)MAX_SLV3_SGPCR3 = 0x00080000; /* // Enable Host 2 TxEn pin *(VP_U32)OTG_SYS_CTRL &= 0xFFFFFFF9; *(VP_U32)OTG_SYS_CTRL |= 0x00000002;*/ //set to disable the pull up so that re-enumeration will be issue if enter bootstrap again *(VP_U32)(OTG_CORE_HNP_CSTAT) &= ~0x00000800; }//0404//======================================// Configure the OTG to behave as Func//======================================inline void OtgFuncCommonInit(void){// int countdown = TIMEOUT_VALUE;// int UsbPresent = 1; U32 tempval; U32 timeout = TIMEOUT_VALUE; r_i2cHwSw = 1; SetOtgPort_FunctionMode(); /* OTG port forced as function *///*************************************// add the USB transceiver on/off here //************************************* OtgPort_ExtPullUpDisabled(); /* disable internal pullup resistor */ tempval = *(VP_U32)(OTG_CORE_CLK_CTRL); *(VP_U32)(OTG_CORE_CLK_CTRL) = (tempval | 0x4); /* Bit2=FunctionEnable */ //wait for the FUNCCLK and MAINCLK to be set while(!((*(VP_U32)OTG_CORE_CLK_CTRL) & 0x5)) { timeout--; if (!timeout) break; } // Disable all and D- pulldown. func_i2cSingleRegWrite(OTG_CTRL_REG1_CLR_ADD, 0); func_i2cSingleRegWrite(OTG_CTRL_REG1_SET_ADD, (U8)I2C_MASK_DM_PULLDOWN); /* D+ pull-up disable */ //disable the D+ first. Func_Init_I2C_disable(); //20030821 begin if (*(volatile p_uint32_t)OTG_FUNC_CND_STAT & BIT0) //RESET DET set *(volatile p_uint32_t)OTG_FUNC_CND_STAT = 0x0; if (*(volatile p_uint32_t)OTG_FUNC_SINT_STAT & BIT0) *(volatile p_uint32_t)OTG_FUNC_SINT_STAT = BIT0;//20030821 end//*************************************// add the USB transceiver on/off here //************************************* /* D+ pull-up */ Func_Init_I2C(); //enable the D+ /* 20030821 begin if (*(VP_U32)OTG_FUNC_CND_STAT & 0x1) *(VP_U32)OTG_FUNC_CND_STAT = 0x0; if (*(VP_U32)OTG_FUNC_SINT_STAT & 0x1) *(VP_U32)OTG_FUNC_SINT_STAT = 0x1;20030821 end*/ //void EPConfig(U32 ep, U32 dir, U32 stall, U32 setup, U32 MPS, U32 format, U32 xbsa, U32 ybsa, U32 Bufsize, U32 Tbyte){ /* Configure EP0 for CTRL SETUP (8 bytes) */// EPConfig(0, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 7, 8); EPConfig(0, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 8, 8); Enable_EP(0); /* Enable EP0-OUT to accept CTRL SETUP */ Ready_EP_OUT(0); /* Ready EP0 */ Enable_EP(1); /* Enable EP0-IN to accept CTRL DATA, if ready not set will return NAK */ Enable_EP(3); //enable EP1 OUT Enable_EP(4); //enable EP2 IN}//*******************************************************************// HandleDevReq.cvoid processCommand(){ U32 ep_num = 0; //EP number U32 ep = 0; U8 dir = 0; // U32 mask = 0; U32 EpStartAddress = 0; U32 TempBuffer = 0; U8 i = 0; U8 j = 0; U8 * ReadPtr8; U16 * ReadPtr16; U32 * ReadPtr32; U32 * DataBuf; U32 tmp; //use Usb to Get the Command, EP1 as BULK OUT { ep = 2; dir = EP_OUT_DIR; ep_num = (ep*2) + dir; mask = 1 << ep_num; //read the Start Address (xbsa, ybsa) if (EpNextBufToService & (mask)) //X Buffer EpStartAddress = ((*(VP_U32)(OTG_EP_BASE+(16*ep_num)+4))&0x0000FFFF); else //Y Buffer EpStartAddress = (((*(VP_U32)(OTG_EP_BASE+(16*ep_num)+4))>>16)&0x0000FFFF); //read and decode the 16 byte Setup Packet 32bit access for (i=0;i<8;i++) { TempBuffer = *(VP_U32)(OTG_DATA_BASE + EpStartAddress + i*4); for (j=0;j<4;j++) _gCBW[4*i+j] = (U8)((TempBuffer >> 8*j) & 0xFF); } //Set/Clear Fill Status SetClearFillStatus(mask); ClearXYBufferInt(); } //EUARTputString("_gCBW[15]=0x"); //EUARTputHex(_gCBW[15]); //EUARTputString("\n"); switch(_gCBW[15]) { case 0x12: // inquiry, //EP1 as BULK IN EPConfig(EP1, EP_IN_DIR, 0, 0, 32, BLK_TYPE, 0x100, 0x200, 64, 36); //read the Start Address (xbsa, ybsa) if (EpNextBufToService & (EP1IN)) //X Buffer EpStartAddress = ((*(VP_U32)(OTG_EP_BASE+(16*3)+4))&0x0000FFFF); else //Y Buffer EpStartAddress = (((*(VP_U32)(OTG_EP_BASE+(16*3)+4))>>16)&0x0000FFFF); //write data to buffer ClearXYBufferInt();//ClearXYBufferInt(); DataBuf=(U32 *)(OTG_DATA_BASE + EpStartAddress); *(DataBuf++)=0x01008000; //Endian(0x00800001); *(DataBuf++)=0x0000005B; //Endian(0x5B000000); *(DataBuf++)=0x4f544f4d; //Endian(0x4D4F544F); // "MOTO" *(DataBuf++)=0x414c4f52; //Endian(0x524F4C41); // "ROLA" *(DataBuf++)=0x2032584d; //Endian(0x4D583120); // "MX2 " *(DataBuf++)=0x20534441; //Endian(0x41445320); // "ADS " *(DataBuf++)=0x20312e30; //Endian(0x302E3120); // "0.1 " *(DataBuf++)=0x20202020; //Endian(0x20202020); // " " *(DataBuf++)=0x30303130; //Endian(0x30303130); SetClearFillStatus(EP1IN); Ready_EP_IN(1); while (!(*(VP_U32)OTG_FUNC_EP_DSTAT & EP1IN)); *(VP_U32)OTG_FUNC_EP_DSTAT = EP1IN; ClearXYBufferInt(); unready_ep_in(EP1); EPConfig(EP1, EP_IN_DIR, 0, 0, 32, BLK_TYPE, 0x100, 0x200, 32, 13); DataBuf=(U32 *)(OTG_DATA_BASE + EpStartAddress); // now the CSW *(DataBuf++)=0x53425355; // signature tmp = 0; tmp |= _gCBW[7]; tmp<<=8; tmp |= _gCBW[6]; tmp<<=8; tmp |= _gCBW[5]; tmp<<=8; tmp |= _gCBW[4]; *(DataBuf++)= tmp; *(DataBuf++)=0; *((U8*)DataBuf)=0; //Set/Clear Fill Status ClearXYBufferInt(); SetClearFillStatus(EP1IN); Ready_EP_IN(1); //ready EP2 //check for EP2 IN transfer done while (!(*(VP_U32)OTG_FUNC_EP_DSTAT & EP1IN)); //clear EP0 IN transfer done *(VP_U32)OTG_FUNC_EP_DSTAT = EP1IN; ClearXYBufferInt(); unready_ep_in(EP1); break; case 0x23: // READ FORMAT CAPACITIES, not supported, return STALL case 0x1A: // MODE SENSE, not supported, return STALL case 0x5A: // MODE SENSE, not supported, return STALL EPConfig(EP1, EP_IN_DIR, EP_NO_STALL, 0, 32, BLK_TYPE, 0x100, 0x200, 32, 0); if (EpNextBufToService & (EP1IN)) //X Buffer EpStartAddress = ((*(U32 *)(OTG_EP_BASE+(16*3)+4))&0x0000FFFF); else //Y Buffer EpStartAddress = (((*(U32 *)(OTG_EP_BASE+(16*3)+4))>>16)&0x0000FFFF); ClearXYBufferInt(); SetClearFillStatus(EP1IN); Ready_EP_IN(1); //ready EP1 //check for EP1 IN transfer done while (!(*(U32 *)OTG_FUNC_EP_DSTAT & EP1IN)); //clear EP1 IN transfer done *(U32 *)OTG_FUNC_EP_DSTAT = EP1IN; ClearXYBufferInt(); unready_ep_in(EP1); EPConfig(EP1, EP_IN_DIR, EP_NO_STALL, 0 , 32, BLK_TYPE, 0x100, 0x200, 32, 13); DataBuf=(U32 *)(OTG_DATA_BASE + EpStartAddress); // now the CSW *(DataBuf++) =0x53425355; // signature tmp = 0; tmp |= _gCBW[7]; tmp<<=8; tmp |= _gCBW[6]; tmp<<=8; tmp |= _gCBW[5]; tmp<<=8; tmp |= _gCBW[4]; *(DataBuf++) = tmp; tmp = 0; tmp |= _gCBW[11]; tmp<<=8; tmp |= _gCBW[10]; tmp<<=8; tmp |= _gCBW[9]; tmp<<=8; tmp |= _gCBW[8]; *(DataBuf++) = tmp; //1 byte *((U8 *)DataBuf) = 0x01; //status: failed ClearXYBufferInt(); SetClearFillStatus(EP1IN); Ready_EP_IN(EP1); //ready EP1 //check for EP1 IN transfer done while (!(*(U32 *)OTG_FUNC_EP_DSTAT & EP1IN)); //clear EP1 IN transfer done *(U32 *)OTG_FUNC_EP_DSTAT = EP1IN; ClearXYBufferInt(); unready_ep_in(EP1); break; case 0x03: // REQUEST SENSE, return error EPConfig(EP1, EP_IN_DIR, 0, 0, 32, BLK_TYPE, 0x100, 0x200, 32, 18); //read the Start Address (xbsa, ybsa) if (EpNextBufToService & (EP1IN)) //X Buffer EpStartAddress = ((*(U32 *)(OTG_EP_BASE+(16*3)+4))&0x0000FFFF);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -