⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbrx.c

📁 mx21的NAND Flash Bootloader源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -