mx27_habtools.c

来自「NorFlash bootloader(SPANSION_S71WS256ND0」· C语言 代码 · 共 844 行 · 第 1/2 页

C
844
字号
	qhead.TotalBytes  	= TotalBytes;	qhead.ioc 			= IOC_SET;	qhead.Status 		= NO_STATUS;	qhead.BuffPtr0  	= BUFPTR_P0_EP1OUT;	qhead.CurrentOffset = (BUFPTR_P0_EP1OUT & 0xFFF);	qhead.BuffPtr1  	= 0;	qhead.BuffPtr2 		= 0;	qhead.BuffPtr3  	= 0;	qhead.BuffPtr4 = 0;			// EP1 OUT command = 16 bytes	SetupQHead(&qhead);		// Endpoint 1 : MPS = 64, OUT (Rx endpoint)	*(P_U32)USB_OTG_ENDPTCTRL1 = 0x00080048;	// Enable EP1 OUT	*(P_U32)USB_OTG_ENDPTCTRL1 |= EP1OUT_ENABLE;}/*==================================================================================================FUNCTION: EP1OutCommandSetupDESCRIPTION:    	This function is used to prepare the Setup command from PC and prime the endpointARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void EP1OutCommandSetup(void){	U32 TotalBytes = COMMAND;	struct s_dTD td;// OUT	// setup dTD	// dTD for status of GET_DEVICE_DESCRIPTOR	td.dTDBase 			= dTD0_EP1OUT;	td.dTDNextLinkPtr  	= dTD1_EP1OUT;	td.Terminate 		= TERMINATE;	td.TotalBytes  		= TotalBytes;	td.ioc 				= IOC_SET;	td.Status 			= ACTIVE;	td.BuffPtr0  		= BUFPTR_P0_EP1OUT;	td.CurrentOffset 	= (BUFPTR_P0_EP1OUT & 0xFFF);	td.BuffPtr1  		= 0;	td.BuffPtr2 		= 0;	td.BuffPtr3  		= 0;	td.BuffPtr4  		= 0;	SetupTransferDescriptor(&td);	// 1. write dQH next ptr and dQH terminate bit to 0 	*(P_U32)(dQH2_EP1OUT+0x8)= (dTD0_EP1OUT);		// 2. clear active & halt bit in dQH	*(P_U32)(dQH2_EP1OUT+0xC) &= ~0xFF;		// 3. prime endpoint by writing '1' in ENDPTPRIME	*(P_U32)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME;	}/*==================================================================================================FUNCTION: EP1OutRxDataDESCRIPTION:    	This function is used to rx binary data for the downloadARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void EP1OutRxData(U32 Address, U32 Offset, U32 ByteCount){	struct s_dTD td;	// setting up the dTD buffer pointer depend on the ByteCounts	// each page is 0x1000 and the max recommanded transfer is 0x4000 (16k bytes)	U32 BufferPtrPage0 = Address;	U32 BufferPtrPage1 = (Address + 0x1000);	U32 BufferPtrPage2 = (Address + 0x2000);	U32 BufferPtrPage3 = (Address + 0x3000);	U32 BufferPtrPage4 = (Address + 0x4000);		// Clear the EP1 OUT complete status if set	if (*(P_U32)USB_OTG_ENDPTCOMPLETE & BIT1)		*(P_U32)USB_OTG_ENDPTCOMPLETE = BIT1;	// OUT	// setup dTD	// dTD for status of GET_DEVICE_DESCRIPTOR	td.dTDBase 			= dTD0_EP1OUT;	td.dTDNextLinkPtr  	= dTD1_EP1OUT;	td.Terminate 		= TERMINATE;	td.TotalBytes  		= ByteCount;	td.ioc 				= IOC_SET;	td.Status 			= ACTIVE;	td.BuffPtr0  		= BufferPtrPage0; 	td.CurrentOffset 	= Offset; 	td.BuffPtr1  		= BufferPtrPage1;	td.BuffPtr2 		= BufferPtrPage2;	td.BuffPtr3  		= BufferPtrPage3;	td.BuffPtr4  		= BufferPtrPage4;	SetupTransferDescriptor(&td);	// 1. write dQH next ptr and dQH terminate bit to 0 	*(P_U32)(dQH2_EP1OUT+0x8)= (dTD0_EP1OUT);		// 2. clear active & halt bit in dQH	*(P_U32)(dQH2_EP1OUT+0xC) &= ~0xFF;		// 3. prime endpoint by writing '1' in ENDPTPRIME	*(P_U32)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME;		// 4. Wait for the Complete Status 	while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & BIT1));	//clear the complete status	*(VP_U32)USB_OTG_ENDPTCOMPLETE = BIT1;}/*==================================================================================================FUNCTION: EnableEP2INDESCRIPTION:    	This function is used to enable the EP2 as INARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void EnableEP2IN(void){	// EP2 IN response = 4 bytes	U32 TotalBytes = 0x4;	struct s_dQH qhead;		qhead.dQHBase 		= dQH5_EP2IN;	qhead.ZLT 			= ZLT_DISABLE;	qhead.MPS 			= MPS_64;	qhead.ios 			= IOS_SET;	qhead.NextLinkPtr  	= dTD0_EP2IN;	qhead.Terminate 	= TERMINATE;	qhead.TotalBytes  	= TotalBytes;	qhead.ioc 			= IOC_SET;	qhead.Status 		= NO_STATUS;	qhead.BuffPtr0  	= BUFPTR_P0_EP2IN;	qhead.CurrentOffset = (BUFPTR_P0_EP2IN & 0xFFF);	qhead.BuffPtr1  	= 0;	qhead.BuffPtr2 		= 0;	qhead.BuffPtr3  	= 0;	qhead.BuffPtr4 		= 0;			// EP1 OUT command = 16 bytes	SetupQHead(&qhead);	// Endpoint 2: MPS = 64, IN (Tx endpoint)	*(P_U32)USB_OTG_ENDPTCTRL2 = 0x00480008;	// Enable EP2 IN	*(P_U32)USB_OTG_ENDPTCTRL2 |= EP2IN_ENABLE;		// 3. prime endpoint by writing '1' in ENDPTPRIME	*(P_U32)USB_OTG_ENDPTPRIME |= EP2IN_PRIME;	}/*==================================================================================================FUNCTION: CommandAckDESCRIPTION:    	This function is used to prepare the 4 bytes response to USB HostARGUMENTS PASSED:	U32 ack: response  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void CommandAck(U32 ack,  U8 channel){	struct s_dTD td;	U32 TotalBytes = 0x4;	if (channel)	{		*(P_U32)BUFPTR_P0_EP2IN = ack;				td.dTDBase 			= dTD0_EP2IN;		td.dTDNextLinkPtr  	= dTD1_EP2IN;		td.Terminate 		= TERMINATE;		td.TotalBytes  		= TotalBytes;		td.ioc 				= IOC_SET;		td.Status 			= ACTIVE;		td.BuffPtr0  		= BUFPTR_P0_EP2IN;		td.CurrentOffset 	= (BUFPTR_P0_EP2IN & 0xFFF); 		td.BuffPtr1  		= 0;		td.BuffPtr2 		= 0;		td.BuffPtr3  		= 0;		td.BuffPtr4  		= 0;		SetupTransferDescriptor(&td);				// 1. write dQH next ptr and dQH terminate bit to 0 		*(P_U32)(dQH5_EP2IN+0x8)= (dTD0_EP2IN);				// 2. clear active & halt bit in dQH		*(P_U32)(dQH5_EP2IN+0xC) &= ~0xFF;				// 3. prime endpoint by writing '1' in ENDPTPRIME		*(P_U32)USB_OTG_ENDPTPRIME = EP2IN_PRIME;				// wait for complete set and clear		while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & EP2IN_COMPLETE));				*(P_U32)USB_OTG_ENDPTCOMPLETE = EP2IN_COMPLETE;	}//#######	// UART//#######		else 	{		MX31_PutCharInFIFO((U8)ack & 0xFF);		MX31_PutCharInFIFO((U8)((ack & 0xFF00)>>8));		MX31_PutCharInFIFO((U8)((ack & 0xFF0000)>>16));		MX31_PutCharInFIFO((U8)((ack & 0xFF000000)>>24));		//wait for TF empty		while (!(*(VP_U32)UART1_USR2_1 & 0x4000));		}	}	/*==================================================================================================FUNCTION: EP2INTxDataDESCRIPTION:    	This function is used to transmit the data for READ commandARGUMENTS PASSED:	U32 BufPtrAddress - Buffer pointer address	U32 TotalBytes	  - TotalBytes to be read  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void EP2INTxData(U32 BufPtrAddress, U32 TotalBytes){	struct s_dTD td;		td.dTDBase 			= dTD0_EP2IN;	td.dTDNextLinkPtr  	= dTD1_EP2IN;	td.Terminate 		= TERMINATE;	td.TotalBytes  		= TotalBytes;	td.ioc 				= IOC_SET;	td.Status 			= ACTIVE;	td.BuffPtr0  		= BufPtrAddress;	td.CurrentOffset 	= 0; 	td.BuffPtr1  		= 0;	td.BuffPtr2 		= 0;	td.BuffPtr3  		= 0;	td.BuffPtr4  		= 0;	SetupTransferDescriptor(&td);		// 1. write dQH next ptr and dQH terminate bit to 0 	*(P_U32)(dQH5_EP2IN+0x8)= (dTD0_EP2IN);		// 2. clear active & halt bit in dQH	*(P_U32)(dQH5_EP2IN+0xC) &= ~0xFF;		// 3. prime endpoint by writing '1' in ENDPTPRIME	*(P_U32)USB_OTG_ENDPTPRIME = EP2IN_PRIME;		// wait for complete set and clear	while (!(*(VP_U32)USB_OTG_ENDPTCOMPLETE & EP2IN_COMPLETE));		*(P_U32)USB_OTG_ENDPTCOMPLETE = EP2IN_COMPLETE;}/*==================================================================================================FUNCTION: HandleCommandDESCRIPTION:    	This function is used to handle the PC CommandARGUMENTS PASSED:	U8 ErrorCode: Error Code passed from HAB  RETURN VALUE:	DONE (1)	: when Execute = 0xAA, return to Bootstrap	CONTINUE (0) : for others	IMPORTANT NOTES:	None		==================================================================================================*/int HandleCommand(int status, int count, U8 channel){	int i = 0;	U16 Header = 0;	U32 Response = 0;	P_U32 BufPtr;		// USB	if (channel)	{		BufPtr = (P_U32)BUFPTR_P0_EP1OUT;		for (i=0; i < 16; i += 4)		{			_gCommand[i] = 0x0;			_gCommand[i] = (U8) (*BufPtr & 0xff);							_gCommand[i + 1] = 0x0;			_gCommand[i + 1] = (U8) ((*BufPtr >> 8)  & 0xff);			_gCommand[i + 2] = 0x0;			_gCommand[i + 2] = (U8) ((*BufPtr >> 16)  & 0xff);			_gCommand[i + 3] = 0x0;			_gCommand[i + 3] = (U8) ((*BufPtr >> 24)  & 0xff);						BufPtr++;		}			}			// UART here	else	{		for (i=0; i< 16; i++)		{			while (!(*(VP_U32)UART1_USR2_1 & 0x1));			_gCommand[i] = MX31_GetCharFromFIFO(); 		}	}	Header = ((_gCommand[0]<<8) | (_gCommand[1]));	{		Response =( (status << 16) | count) ;		CommandAck(Response, channel);	}	return 1;}unsigned char MX31_GetCharFromFIFO (void){	return (*(VP_U32)UART1_URXD_1 & 0xFF);}// PutCharInFIFOvoid MX31_PutCharInFIFO (unsigned char c){	 *(VP_U32)UART1_UTXD_1 = c;}void HAB_flash_status(int status, int count, U8 channel){		if (channel)	{		//if ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & BIT1)					while(! ((*(VP_U32)USB_OTG_ENDPTCOMPLETE) & BIT1));					{										*(P_U32)USB_OTG_ENDPTCOMPLETE = BIT1;											HandleCommand(status, count, channel);			EP1OutCommandSetup();		}		}	else	{		while (!(*(VP_U32)UART1_USR2_1 & 0x1));	//	if (*(VP_U32)UART1_USR2_1 & 0x1)							HandleCommand(status, count, channel);	}}

⌨️ 快捷键说明

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