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

📄 otg_dev.c

📁 s3c6410基于USB OTG下载内核至NORFLASH的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#define INT_IN_EP0					(0x1<<0)
#define INT_IN_EP1					(0x1<<1)
#define INT_IN_EP3					(0x1<<3)
#define INT_OUT_EP0					(0x1<<16)
#define INT_OUT_EP2					(0x1<<18)
#define INT_OUT_EP4					(0x1<<20)

// DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register
#define DEPCTL_EPENA				(0x1<<31)
#define DEPCTL_EPDIS				(0x1<<30)
#define DEPCTL_SNAK					(0x1<<27)
#define DEPCTL_CNAK					(0x1<<26)
#define DEPCTL_CTRL_TYPE			(EP_TYPE_CONTROL<<18)
#define DEPCTL_ISO_TYPE				(EP_TYPE_ISOCHRONOUS<<18)
#define DEPCTL_BULK_TYPE			(EP_TYPE_BULK<<18)
#define DEPCTL_INTR_TYPE			(EP_TYPE_INTERRUPT<<18)
#define DEPCTL_USBACTEP				(0x1<<15)
#define DEPCTL0_MPS_64				(0x0<<0)
#define DEPCTL0_MPS_32				(0x1<<0)
#define DEPCTL0_MPS_16				(0x2<<0)
#define DEPCTL0_MPS_8				(0x3<<0)

// DIEPCTLn/DOEPCTLn device control IN/OUT endpoint n control register

// DIEPMSK/DOEPMSK device IN/OUT endpoint common interrupt mask register
// DIEPINTn/DOEPINTn device IN/OUT endpoint interrupt register
#define BACK2BACK_SETUP_RECEIVED  		(0x1<<6)
#define INTKN_TXFEMP					(0x1<<4)
#define NON_ISO_IN_EP_TIMEOUT			(0x1<<3)
#define CTRL_OUT_EP_SETUP_PHASE_DONE	(0x1<<3)
#define AHB_ERROR						(0x1<<2)
#define TRANSFER_DONE					(0x1<<0)

 

//=====================================================================
// setting the device qualifier descriptor and a string descriptor
const u8 aDeviceQualifierDescriptor[] =
{
	0x0a,                   //  0 desc size
	0x06,                   //  1 desc type (DEVICE_QUALIFIER)
	0x00,                   //  2 USB release
	0x02,                   //  3 => 2.00
	0xFF,                   //  4 class
	0x00,                   //  5 subclass
	0x00,                   //  6 protocol
	64,          			//  7 max pack size
	0x01,                   //  8 number of other-speed configuration
	0x00,                   //  9 reserved
};

const u8 aOtherSpeedConfiguration_full[] =
{
	0x09,                   //  0 desc size
	0x07,                   //  1 desc type (other speed)
	0x20,                   //  2 Total length of data returned
	0x00,                   //  3 
	0x01,                   //  4 Number of interfaces supported by this speed configuration
	0x01,                   //  5 value to use to select configuration
	0x00,                   //  6 index of string desc
	CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED,   //  7 same as configuration desc
	0x19,                   //  8 same as configuration desc
	
};

const u8 aOtherSpeedConfiguration_fullTotal[] =
{
  0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19,
  0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00,
  0x07 ,0x05 ,0x83 ,0x02 ,0x40 ,0x00 ,0x00,
  0x07 ,0x05 ,0x04 ,0x02 ,0x40 ,0x00 ,0x00
};

const u8 aOtherSpeedConfiguration_high[] =
{
	0x09,                   //  0 desc size
	0x07,                   //  1 desc type (other speed)
	0x20,                   //  2 Total length of data returned
	0x00,                   //  3 
	0x01,                   //  4 Number of interfaces supported by this speed configuration
	0x01,                   //  5 value to use to select configuration
	0x00,                   //  6 index of string desc
	CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED,   //  7 same as configuration desc
	0x19,                   //  8 same as configuration desc
	
};

const u8 aOtherSpeedConfiguration_highTotal[] =
{
  0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19,
  0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00,
  0x07 ,0x05 ,0x81 ,0x02 ,0x00 ,0x02 ,0x00,
  0x07 ,0x05 ,0x02 ,0x02 ,0x00 ,0x02 ,0x00
};

const u8 aDescStr0[]=
{
	4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H, // codes representing languages
};

const u8 aDescStr1[]= // Manufacturer
{
	(0x14+2), STRING_DESCRIPTOR,
	'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0, 'm', 0x0, ' ', 0x0, 'M', 0x0,
	'C', 0x0, 'U', 0x0,
};

const u8 aDescStr2[]= // Product
{
	(0x2a+2), STRING_DESCRIPTOR,
	'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0, '3', 0x0, 'C', 0x0, '6', 0x0,
	'4', 0x0, '1', 0x0, '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0, 's', 0x0,
	't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0, 'D', 0x0
};


//=====================================================================
// global varibles used in several functions
OTGDEV oOtgDev;
USB_GET_STATUS oStatusGet;
USB_INTERFACE_GET oInterfaceGet;

u16 g_usConfig;
u16 g_usUploadPktLength=0;
bool g_bTransferEp0 = false;

//////////
// Function Name : OTGDEV_InitOtg
// Function Desctiption : This function initializes OTG PHY and LINK.
// Input : eSpeed, USB Speed (high or full)
// Output : NONE
// Version :
void OTGDEV_InitOtg(USB_SPEED eSpeed)
{
	u8 ucMode;
	
	Outp32SYSC(0x804,Inp32SYSC(0x804)&~(1<<17));	//enable OTG clock pad
	Outp32SYSC(0x900,Inp32SYSC(0x900)|(1<<16));	//unmask usb signal
	 
	oOtgDev.m_eSpeed = eSpeed;
	oOtgDev.m_uIsUsbOtgSetConfiguration = 0;
	oOtgDev.m_uEp0State = EP0_STATE_INIT;
	oOtgDev.m_uEp0SubState = 0;
	OTGDEV_InitPhyCon();
	OTGDEV_SoftResetCore();
	OTGDEV_WaitCableInsertion();
	OTGDEV_InitCore();
	OTGDEV_CheckCurrentMode(&ucMode);
	if (ucMode == INT_DEV_MODE)
	{
		OTGDEV_SetSoftDisconnect();
		Delay(10);
		OTGDEV_ClearSoftDisconnect();
		OTGDEV_InitDevice();
	}
	else
	{
		Disp("Error : Current Mode is Host\n");
		return;
	}
}

//////////
// Function Name : OTGDEV_HandleEvent
// Function Desctiption : This function handles various OTG interrupts of Device mode.
// Input : NONE
// Output : NONE
// Version :
void OTGDEV_HandleEvent(void)
{
	u32 uGIntStatus, uDStatus;
	u32 ep_int_status, ep_int;

	uGIntStatus = Inp32(GINTSTS); // System status read
	Outp32(GINTSTS, uGIntStatus); // Interrupt Clear		
	DbgUsb0("GINTSTS : %x \n", uGIntStatus);

	if (uGIntStatus & INT_RESET) // Reset interrupt
	{
		Outp32(DCTL,Inp32(DCTL) & ~(TEST_CONTROL_FIELD));
		OTGDEV_SetAllOutEpNak();
		oOtgDev.m_uEp0State = EP0_STATE_INIT;
		Outp32(DAINTMSK,((1<<BULK_OUT_EP)|(1<<CONTROL_EP))<<16|((1<<BULK_IN_EP)|(1<<CONTROL_EP)));
		Outp32(DOEPMSK, CTRL_OUT_EP_SETUP_PHASE_DONE|AHB_ERROR|TRANSFER_DONE);
		Outp32(DIEPMSK, INTKN_TXFEMP|NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE);
		Outp32(GRXFSIZ, RX_FIFO_SIZE);					// Rx FIFO Size
		Outp32(GNPTXFSIZ, NPTX_FIFO_SIZE<<16| NPTX_FIFO_START_ADDR<<0);	// Non Periodic Tx FIFO Size		
		OTGDEV_ClearAllOutEpNak();
		Outp32(DCFG, Inp32(DCFG)&~(0x7f<<4));	//clear device address
		if(g_bSuspendResume==true)
		{
			Disp("\n [USB_Diag_Log]  : Reset Mode\n");
		}
		else
		{
			DbgUsb("\n [USB_Diag_Log]  : Reset Mode\n");
		}
		
		Outp32(PCGCCTRL, Inp32(PCGCCTRL)&~(1<<0));	//start pclk
		DbgUsb("rOTHERS=0x%08x\n",Inp32SYSC(0x900));
	}

	if (uGIntStatus & INT_ENUMDONE) // Device Speed Detection interrupt
	{
		DbgUsb("\n [USB_Diag_Log]  : Speed Detection interrupt \n");
		
		uDStatus = Inp32(DSTS); // System status read

		if (((uDStatus&0x6) >>1) == USB_HIGH) 			// Set if Device is High speed or Full speed
		{
			DbgUsb("\n [USB_Diag_Log]  : High Speed Detection\n");
			OTGDEV_SetMaxPktSizes(USB_HIGH);
		}
		else if(((uDStatus&0x6) >>1) == USB_FULL)
		{
			DbgUsb("\n [USB_Diag_Log]  : full Speed Detection\n");
			OTGDEV_SetMaxPktSizes(USB_FULL);
		}
		else
		{
			Disp("\n Error:Neither High_Speed nor Full_Speed\n");
			return;
		}
		
		OTGDEV_SetEndpoint();
		OTGDEV_SetDescriptorTable();
	}
	
	if (uGIntStatus & INT_RESUME)
	{
		if(g_bSuspendResume==true)
		{
			Disp("\n [USB_Diag_Log]  : Resume Mode \n");
		}
		else
		{
			DbgUsb("\n [USB_Diag_Log]  : Resume Mode \n");
		}
		
		Outp32(PCGCCTRL, Inp32(PCGCCTRL)&~(1<<0));	//start pclk
	}

	if (uGIntStatus & INT_SUSPEND)
	{
		if(g_bSuspendResume==true)
		{
			Disp("\n [USB_Diag_Log]  : Suspend Mode\n");
		}
		else
		{
			DbgUsb("\n [USB_Diag_Log]  : Suspend Mode\n");
		}
		
		Outp32(PCGCCTRL, Inp32(PCGCCTRL)|(1<<0));	//stop pclk
		DbgUsb("rOTHERS=0x%08x\n",Inp32SYSC(0x900));
	}

	if(uGIntStatus & INT_RX_FIFO_NOT_EMPTY)
	{
		u32 GrxStatus;
		u32 fifoCntByte;

		DbgUsb("INT_RX_FIFO_NOT_EMPTY\n");
		Outp32(GINTMSK,  INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE|INT_RESET|INT_SUSPEND);
		
		GrxStatus = Inp32(GRXSTSP);
		DbgUsb("GRXSTSP : %x \n", GrxStatus);
	
		if ((GrxStatus & SETUP_PKT_RECEIVED) == SETUP_PKT_RECEIVED) 
		{
			DbgUsb("SETUP_PACKET_RECEIVED\n");
			OTGDEV_HandleEvent_EP0();
			g_bTransferEp0=true;
		}
		else if ((GrxStatus & OUT_PKT_RECEIVED) == OUT_PKT_RECEIVED)
		{
			fifoCntByte = (GrxStatus & 0x7ff0)>>4;
			if(((GrxStatus&0xf)==BULK_OUT_EP)&&(fifoCntByte))
			{				
				DbgUsb("Bulk Out : OUT_PKT_RECEIVED\n");
				OTGDEV_HandleEvent_BulkOut(fifoCntByte);
				if( oOtgDev.m_eOpMode == USB_CPU )
					Outp32(GINTMSK, INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE|INT_RESET|INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY);
				return;
			}
		}
		Outp32(GINTMSK, INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE|INT_RESET
			|INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY); //gint unmask
	}

	if ((uGIntStatus & INT_IN_EP) || (uGIntStatus & INT_OUT_EP))
	{
		u32 uDmaEnCheck;
		s32 uRemainCnt; 
		
		ep_int = Inp32(DAINT);
		DbgUsb("DAINT : %x \n", ep_int);
		
		if (ep_int & (1<<CONTROL_EP))
		{
			ep_int_status = Inp32(DIEPINT0);
			DbgUsb("DIEPINT0 : %x \n", ep_int_status);
			
			if (ep_int_status & INTKN_TXFEMP)
			{
				if (g_bTransferEp0==true)
				{
					OTGDEV_TransferEp0();
					g_bTransferEp0 = false;
				}
			}
			
			Outp32(DIEPINT0, ep_int_status); // Interrupt Clear
		}
		
		if (ep_int & ((1<<CONTROL_EP)<<16))
		{
			ep_int_status = Inp32(DOEPINT0);
			DbgUsb("DOEPINT0 : %x \n", ep_int_status);
			
			OTGDEV_SetOutEpXferSize(EP_TYPE_CONTROL, 1, oOtgDev.m_uControlEPMaxPktSize);
			Outp32(DOEPCTL0, 1u<<31|1<<26);		//ep0 enable, clear nak
			
			Outp32(DOEPINT0, ep_int_status); 		// Interrupt Clear
		}

		if(ep_int & (1<<BULK_IN_EP))
		{
			ep_int_status = Inp32(bulkIn_DIEPINT);
 			DbgUsb0("bulkIn_DIEPINT : %x \n", ep_int_status);
			Outp32(bulkIn_DIEPINT, ep_int_status); // Interrupt Clear	
			
			uDmaEnCheck = Inp32(GAHBCFG);
			
			if (oOtgDev.m_eOpMode == USB_CPU)
			{
				if (ep_int_status&TRANSFER_DONE)
				{
					Outp32(bulkIn_DIEPINT, TRANSFER_DONE); // Interrupt Clear
					
					oOtgDev.m_pUpPt += g_usUploadPktLength;
					OTGDEV_HandleEvent_BulkIn();
				}
			}
			
			else if ((uDmaEnCheck&MODE_DMA)&&(ep_int_status&TRANSFER_DONE))
			{
				DbgUsb("DMA IN : Transfer Done\n");

				oOtgDev.m_pUpPt = (u8 *)Inp32(bulkIn_DIEPDMA);
				uRemainCnt = oOtgDev.m_uUploadSize- ((u32)oOtgDev.m_pUpPt - oOtgDev.m_uUploadAddr);
				
				if (uRemainCnt>0) 
				{
					u32 uPktCnt, uRemainder;
					uPktCnt = (u32)(uRemainCnt/oOtgDev.m_uBulkInEPMaxPktSize);
					uRemainder = (u32)(uRemainCnt%oOtgDev.m_uBulkInEPMaxPktSize);
					if(uRemainder != 0)
					{
						uPktCnt += 1;
					}
					DbgUsb("uRemainCnt : %d \n", uRemainCnt);
					if (uPktCnt> 1023)
					{
						OTGDEV_SetInEpXferSize(EP_TYPE_BULK, 1023, (oOtgDev.m_uBulkInEPMaxPktSize*1023));
					}
					else
					{
						OTGDEV_SetInEpXferSize(EP_TYPE_BULK, uPktCnt, uRemainCnt);
					}
					Outp32(bulkIn_DIEPCTL, 1u<<31|1<<26|2<<18|1<<15|BULK_IN_EP<<11|oOtgDev.m_uBulkInEPMaxPktSize<<0);		//ep1 enable, clear nak, bulk, usb active, next ep1, max pkt
				}
				else
				{
					DbgUsb("DMA IN : Transfer Complete\n");
				}
			}
		}

		if (ep_int & ((1<<BULK_OUT_EP)<<16))
		{
			ep_int_status = Inp32(bulkOut_DOEPINT);
			Outp32(bulkOut_DOEPINT, ep_int_status); 		// Interrupt Clear
			DbgUsb0("bulkOut_DOEPINT : %x \n", ep_int_status);
			uDmaEnCheck = Inp32(GAHBCFG);
			if ((uDmaEnCheck&MODE_DMA)&&(ep_int_status&TRANSFER_DONE))
			{
				DbgUsb("DMA OUT : Transfer Done\n");
				oOtgDev.m_pDownPt = (u8 *)Inp32(bulkOut_DOEPDMA);

⌨️ 快捷键说明

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