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

📄 usbrx.c

📁 mx21的NAND Flash Bootloader源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
void Enable_EP(U8 ep_num){  U32 ep_state = 0;  U32 mask = 1 << ep_num;  ep_state = *(VP_U32)(OTG_FUNC_EP_EN);      if (ep_state & mask){    /* $display("INFO: Enable_EP was called but EP %0x (%x) was already enabled!", ep_num, ep_state);*/  }  else{    *(VP_U32)(OTG_FUNC_EP_EN) = ep_state | mask; /* enable the EP if it's not enabled*/      }}void WriteEPToggleBit(U8 ep, U8 dir, U8 toggle_val){  U8 ep_num = (ep * 2) + dir ;  U32 temp;  U32 toggle_mask;  U32 mask;  mask = 1 << ep_num;  toggle_mask = toggle_val << ep_num;  temp = *(VP_U32)(OTG_FUNC_EP_TOGGLE);  if ( (temp & mask)  == toggle_mask)  { /* value in OTG_FUNC_EP_TOGGLE is already what is required, nothing is done */  }  else  {      *(VP_U32)(OTG_FUNC_EP_TOGGLE) = toggle_mask;  }}void Ready_EP_IN(U8 ep){    U8 ep_num = (ep * 2) + 1;  U32 mask = 1 << ep_num;   toggle_ready_ep(ep_num, 1);  EP_active = EP_active | mask;    /* set the EP active for DGC purpose */}void Ready_EP_OUT(U8 ep){    U8 ep_num = (ep * 2) + 0;  U32 mask = 1 << ep_num;  toggle_ready_ep(ep_num, 1);  EP_active = EP_active | mask;    /* set the EP active for DGC purpose */}void unready_ep_in(U8 ep){  U8 ep_num = (ep * 2) + 1;  toggle_ready_ep(ep_num, 0);  Clear_active_ep(ep_num);}void unready_ep_out(U8 ep){  U8 ep_num = (ep * 2) + 0;  toggle_ready_ep(ep_num, 0);  Clear_active_ep(ep_num);}void Clear_active_ep(U8 ep_num){  U32 mask = 1 << ep_num;    if (EP_active & mask){ /* if "1", clear to "0" */    EP_active -= mask;  }/*else, do nothing as the Ep is already inactive. */}void toggle_ready_ep(U8 ep_num, U8 ready){  U8   rAlreadyReady;  U32  mask = 1 << ep_num;      rAlreadyReady = check_ep_ready(ep_num);  if (rAlreadyReady && ready){       /*$display("INFO: toggle_ready_ep was called but EP %0x (%x) was already ready! It will not be modified.", ep_num, ep_state);*/  }  else{    if (!rAlreadyReady && !ready){      /*$display("INFO: toggle_ready_ep was called but EP %0x (%x) was already un-ready! It will not be modified.", ep_num, ep_state);*/    }    else{      *(VP_U32)(OTG_FUNC_EP_RDY) = mask; /* write 1 to toggle current state */    }  }}void OtgPort_PullUpEnabled(){    /* need to modify if Non-i2c mode is desired. See TDI's user_tasks.v */  if (r_i2cHwSw){    *(VP_U32)(OTG_CORE_HNP_CSTAT) =  0x00000800;  }  else{    i2cDpPullUp();  }}void i2cDpPullUp(){  i2cSingleRegWrite(OTG_CTRL_REG1_SET_ADD, (U8)I2C_MASK_DP_PULLUP);  i2cSingleRegWrite(OTG_CTRL_REG1_CLR_ADD, (U8)I2C_MASK_DP_PULLDOWN);}void i2cSetSeqOpReg(U8 qWrData){  i2cCheckBusy();  *(VP_U8)(SEQ_OP_REG_ADD)= qWrData;}void i2cCheckBusy(){//  U8 rRdData;  U32 timeout = TIMEOUT_VALUE;   //  rRdData = *(VP_U8)(I2C_OP_CTRL_REG_ADD);  //  if (rRdData & 0x80){     while (*(VP_U8)(I2C_OP_CTRL_REG_ADD) & 0x80) /*busy waiting for bus to become unbusy */ 	{ 		timeout--; 		if (!timeout) 			break; 		 	} // } 	}void i2cSetSeqRdStartAd(U8 qWrData){       i2cCheckBusy();		//wait until i2c not busy   *(VP_U8)(SEQ_RD_STARTAD_ADD) = qWrData;	//write the addr to be configured in i2c to 0x   }/*------------------------------------------------------------------------------------*//*single i2c register write*//*write a byte only*//*wait for i2c Ready interrut event to know the register write is done*//*need to add timer watch dog later*//*need to add xcvr interrupt disable logic later*//*------------------------------------------------------------------------------------*/void i2cSingleRegWrite(U32 qRegAddr, U8 qWrData){    int timeout=TIMEOUT_VALUE;  *(VP_U8)(qRegAddr) = qWrData;  i2cSetSeqOpReg(1);  i2cSetSeqRdStartAd(qRegAddr);  *(VP_U8)(OTG_XCVR_DEVAD_ADD)=0x2d;    /* Poll for i2c ready interrupt --- need to be removed if ISR is used */  /*  while( !(*(VP_U8)(I2C_MASTER_INT_REG_ADD) & 0x02) );  i2cReadyIntHandler();  *///20030821 begin	// Poll for i2c ready interruptd  	while( !(*(volatile p_uint8_t)(I2C_MASTER_INT_REG_ADD) & 0x02) )	{		//pprintf("not ready.\n");		timeout--;		if (!timeout)			break;	}	//clear the RWREADY bit after it set	if (*(volatile p_uint8_t)(I2C_MASTER_INT_REG_ADD) & 0x2)	{		//pprintf("yes, the flag is 1. should be cleared.\n");		*(volatile p_uint8_t)(I2C_MASTER_INT_REG_ADD) = 0x2;		if (*(volatile p_uint8_t)(I2C_MASTER_INT_REG_ADD) & 0x2)		{				EchoMsg("clear is invalid.\n");		}	}  /* End of polling */ //20030821 end  //  while(!eINTI2CREADY);//  eINTI2CREADY = 0; /* Clear the event */  //EchoMsg("i2cSingleRegWrite end.\n");}/*void ToggleNextBufferToService(U8 mask){ // 5) Toggle NextBufferToService //  if (EpNextBufToService & mask) //"1"- set to "0"    EpNextBufToService -= mask;  else //"0" - set to "1" //    EpNextBufToService = EpNextBufToService | mask;}*/void DefaultXBufferToService(U8 mask){    EpNextBufToService = EpNextBufToService | mask;}void SetClearFillStatus(U8 mask){  /* 4) Set/Clear FILL_STATUS  */  if(EpNextBufToService & mask)/* X buffer */    *(VP_U32)(OTG_FUNC_XFILL_STAT) = mask; /*write to toggle the correct EP's X buffer status*/  else /* y buffer */    *(VP_U32)(OTG_FUNC_YFILL_STAT) = mask; /*write to toggle the correct EP's Y buffer status */}//due to teh MOT-ERRATA1;//Software must clear X and Y buffer interruptsvoid ClearXYBufferInt(void){	U32 temp=0;		temp = *(VP_U32)OTG_FUNC_XINT_STAT;	*(VP_U32)OTG_FUNC_XINT_STAT = temp;	temp = *(VP_U32)OTG_FUNC_XINT_STAT;	*(VP_U32)OTG_FUNC_YINT_STAT = temp;		}void EP0OutForRequest(void){	/*  Configure EP0 for CTRL SETUP (8 bytes) */	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 */}void Return0x00(void){	int k=0;	U32 EpStartAddress=0;	EPConfig(EP0, EP_IN_DIR,   0,  0, 8, CTL_TYPE, (0*16),  0x200,   8,    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	//X Buffer Used	EpStartAddress = ((*(VP_U32)(OTG_EP_BASE+(16*1)+4))&0x0000FFFF);				//write the 8 bytes data to the XBuff	for (k=0;k<2;k++)		*(VP_U32)(OTG_DATA_BASE + EpStartAddress + (k*0x4)) = 0x00 ;	ClearXYBufferInt();		//Ready EP0 IN	Ready_EP_IN(EP0);		//Set/Clear Fill Status	SetClearFillStatus(EP0IN);			//to complete the status stage of Setup	EP0Out_StatusStageTransferDone();}void HandleSetupPacket(void){	uint32_t i = 0;	uint32_t j=0;	uint32_t EpStartAddress = 0;	uint32_t TempPtr;		for (i=0;i<8;i++)		_gUsbOtgDevReq [i] = i+1;		//=====================	// Wait for Setup Done	//=====================	// clear EP0 OUT done	*(VP_U32)OTG_FUNC_EP_DSTAT = EP0OUT;	//read the Start Address (xbsa, ybsa)	EpStartAddress = ((*(volatile p_uint32_t)(OTG_EP_BASE + 4))&0x0000FFFF);				//read and decode the 8 byte Setup Packet with 32bit access	for (i=0;i<2;i++)	{		TempPtr = *(p_uint32_t)(OTG_DATA_BASE  + EpStartAddress + i*4);		for (j=0;j<4;j++)			_gUsbOtgDevReq[j+4*i] = (TempPtr >> (j*8));	}	//Set/Clear Fill Status	SetClearFillStatus(EP0OUT);	// Set Address 00 05 02 00 00 00 00 00 	if (_gUsbOtgDevReq[1] == 0x05)		HandleSetAddress();	// Get Descriptor, Device Type 80 06 00 01 00 00 40 00 		else if ((_gUsbOtgDevReq[0] == 0x80) && (_gUsbOtgDevReq[1] == 0x06))		HandleGetDescriptor();				// Set Configuration, 00 09 01 00 00 00 00 00		else if ((_gUsbOtgDevReq[0] == 0x00) && (_gUsbOtgDevReq[1] == 0x09) && (_gUsbOtgDevReq[2] == 0x01))		{		HandleSetConfiguration();		_gSetConfigurationReceived = 1; 	}		else if ((_gUsbOtgDevReq[0] == 0xA1) && (_gUsbOtgDevReq[1]==0xFE) && (_gUsbOtgDevReq[6] == 0x01))	{		if (_gSetConfigurationReceived)		{			for (i=0;i<3;i++)			{				//wait for the 3 more EP0 Done status				if ((*(VP_U32)OTG_FUNC_EP_DSTAT & EP0OUT))				{					HandleSetupPacket();										//  Configure EP0 for CTRL SETUP (8 bytes) 					EPConfig(EP0, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 8, 8); 					// Enable EP0 OUT to accept CTRL SETUP, unless READY bit set, the device will keep NAK the host					Enable_EP(EP0OUT);                          										// Enable EP0 IN to complete the status stage					Enable_EP(EP0IN);                          								// Ready EP0 to ACK the host					Ready_EP_OUT(EP0);                       								}			}		}		// return 0x00 only		Return0x00();	}}//****************************// End of OTG related function//****************************//********************************************************************// usbotg_main.c//********************************************************************U32 Usbotg_main(){	U32 PC_change_Address = 0;	//store the Address to be changed in PC								//0 : no PC change			// jump to the while loop,	// this while loop is used to poll for the EP0 OUT status, for DEVREQ &	// EP1 OUT done status, which is used to received the command from the PC	// exit only when Change PC command received	// Configure EP1 for BULK IN	EPConfig(EP1, EP_IN_DIR,   0,  0, 32, BLK_TYPE, 0x100,  0x200,  32, 32);	Enable_EP(3);	// Configure EP2 for BULK OUT	EPConfig(EP2,EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 32, BLK_TYPE, 0, 0, 32, 31);	Enable_EP(4);                          	Ready_EP_OUT(2);	quit=0;	while (!quit)	{		//=====================		// Wait for Setup Done		//=====================		// wait for EP0 OUT done		if (*(VP_U32)OTG_FUNC_EP_DSTAT & 0x1)		{			HandleSetupPacket();		}				//==========================		// Wait for Bulk OUT at EP1		// Command form PC host (16 bytes)		//==========================		if (*(VP_U32)OTG_FUNC_EP_DSTAT & 0x10)		{			// clear EP2 OUT done			*(VP_U32)OTG_FUNC_EP_DSTAT = 0x10;			ClearXYBufferInt();			unready_ep_out(EP2);						processCommand();           		// Configure EP2 for BULK OUT       		EPConfig(EP2, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 32, BLK_TYPE, 0, 0, 32, 31);			Ready_EP_OUT(2);		}		EPConfig(EP0, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 8, 8); 		Enable_EP(EP0OUT);                          		Enable_EP(EP0IN);                          		Enable_EP(EP1IN);	}		//EchoMsg("Usbotg_main end...\n");	return PC_change_Address;}//*******************************************************************//	usbotg.c//*******************************************************************void EP0Out_StatusStageTransferDone(void){	//EPConfig for EP0 OUT	//DW0 = 0x00080000	 configure EP0 for CTRL setup	//DW1 = 0x00000000	//DW2 reserved	//DW3 = 0x00E00000	TotalByteCnt = 0 bytes//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 (0 bytes) */	EPConfig(0, EP_OUT_DIR, EP_NO_STALL, EP_NO_SETUP, 8, CTL_TYPE, 0, 0, 7, 0); //	Enable_EP(0);                          /* Enable EP0-OUT to accept CTRL SETUP */	Ready_EP_OUT(0);                       /* Ready EP0 */	//check for EP0 OUT transfer done 	while (!(*(VP_U32)OTG_FUNC_EP_DSTAT & 0x1));	//clear EP0 OUT transfer done 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -