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

📄 pe_usb.c

📁 FIC8120方案的 StartCell_Driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	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
				{

⌨️ 快捷键说明

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