www.pudn.com > TMS320F2812usb.rar > USB_TEST.c


#include  
#include "DSP28_Device.h" 
 
#include "type.h" 
#include "sx2.h" 
#include "descriptors.h" 
#include "DEC2812_USB.h"  
#include "ep0req.h" 
 
BOOL Load_descriptors(char length, char* desc); 
BOOL Write_SX2reg(unsigned char addr, unsigned int value); 
BOOL SX2_comwritebyte(unsigned int value); 
BOOL SX2_FifoWrite(int channel,unsigned int *pdata,unsigned length); 
BOOL SX2_FifoWriteSingle(int channel,unsigned int pdata); 
unsigned int SX2_FifoReadSingle(int channel); 
interrupt void XINT1_ISR_A(void); 
 
extern char desctbl[]; 
 
unsigned char keepAliveCnt;	/* counter of Timer0 interrupts */ 
HANDLE codec_command =0; 
HANDLE codec_data=0; 
unsigned int FifoWriteCnt = 0; 
unsigned int epdatar[512] ={0}; 
unsigned int epdataw[512] ={0}; 
unsigned int epdataw1[256] ={0};   
 
unsigned int irqValue;			 /* interrupt register value */ 
unsigned int setupBuff[8];		 /* setup transaction buffer */ 
BOOL sx2Ready;			 /* status byte for POST */  
BOOL sx2BusActivity;	 /* status byte for suspend */  
BOOL sx2EnumOK;			 /* status byte for enumeration complete */ 
BOOL sx2EP0Buf;			 /* status for endpoint 0 buffer */ 
BOOL sx2Setup;			 /* setup flag set in Int0() ISR */ 
BOOL FLAGS_READ = FALSE; /*FIFO的状态读请求*/ 
unsigned int INT_STATUS; 
unsigned int SX2_int;    
 
BOOL readFlag; 
 
unsigned int usbtimeout = 0x400; 
unsigned int regdataread = 0; 	 
 
unsigned int Fifolong = 0;     /*FIFO的长度*/ 
 
unsigned int setupCnt = 0; 
static BOOL setupDat = FALSE; 
 
void main(void) 
{ 
	unsigned int regValue = 0;	 /* register value from a read */ 
//	unsigned int Sx2int = 0;     /*SX2的中断状态*/ 
	unsigned int Usb2or11= 1;    /*USB工作在哪一个标准上*/ 
	unsigned int endpoint0count = 0;/*EP0的数据长度*/ 
	unsigned int endpoint0data[64] ={0};/*EP0的数据缓冲区*/ 
	unsigned int i = 0; 
	unsigned int FifoStatus24 = 0;	/*FIFO24的状态标识*/ 
	unsigned int FifoStatus68 = 0; 	/*FIFO68的状态标识*/ 
	unsigned int Fifostatus = 0; 
	BOOL hshostlink = FALSE; /*为真是高速USB接口,为假是低速USB接口*/ 
//	BOOL codec_runing = FALSE; 
//	BOOL codec_halt = FALSE; 
//	BOOL codec_rev = FALSE; 
//	BOOL codec_play = FALSE; 
//	BOOL codec_datok = FALSE; 
//	BOOL codec_horfull = TRUE; 
//	BOOL codec_back = FALSE;   
//	BOOL sx2EnumOK = FALSE; 
//	unsigned int codec_count = 0; 
//	unsigned int codec_sample = 0; 
//	unsigned int codec_regvalue = 0; 
//	unsigned int audiodata =0; 
	unsigned int RecievedDataLongth = 0; 
//	unsigned int LedCount = 0; /*记录LED定时器的次数*/ 
	unsigned int DataToEndpoint0 = 0;/*写入到Endpoint0的数据缓冲*/ 
//	unsigned long flashbaddr = 0; 
//	unsigned int flashdata = 0; 
//	unsigned int flasherr = 0; 
//	unsigned long flashlong = 0; 
	/*初始化系统*/ 
	InitSysCtrl(); 
 
	/*关中断*/ 
	DINT; 
	IER = 0x0000; 
	IFR = 0x0000; 
 
	/*初始化PIE*/ 
	InitPieCtrl(); 
 
	/*初始化PIE中断矢量表*/ 
	InitPieVectTable();	 
	 
	/*初始化外设*/ 
	InitPeripherals(); 
	 
	/*初始化GPIO*/ 
	InitGpio1(); 
	 
	EALLOW;	// This is needed to write to EALLOW protected registers 
	PieVectTable.XINT1 = &XINT1_ISR_A; 
	EDIS;   // This is needed to disable write to EALLOW protected registers 
	 
	/*初始化ZONE 1区*/ 
	//InitXintf(); 
	/*初始化外部中断*/ 
	InitXIntrupt(); 
	 
	*USB_STS = 1; 
	 
	/*开中断*/ 
	IER |= M_INT1; 
	 
     
	for(;;) 
    	{ 
    		if(GpioDataRegs.GPEDAT.bit.GPIOE0 == 0) 
    		{ 
    			InitGpio(); 
    			SX2_int = *USB_COMMAND & (SX2_INT_ENUMOK + SX2_INT_READY); 
    			if(SX2_int) 
    			{ 
    				EINT;   // Enable Global interrupt INTM 
					ERTM;	// Enable Global realtime interrupt DBGM 
				break; 
			} 
		} 
		else 
		{ 
			InitGpio(); 
			SX2_int = *USB_COMMAND & (SX2_INT_ENUMOK + SX2_INT_READY); 
			EINT;   // Enable Global interrupt INTM 
			ERTM;	// Enable Global realtime interrupt DBGM 
			break; 
		} 
    	} 
	 
	 
	for(;;) 
	{ 
		/* initialize global variables */ 
		readFlag 		= FALSE;	/* false until register read */ 
		sx2Ready		= FALSE;	/* false until POST or wakeup */ 
		sx2BusActivity	= FALSE;	/* false until absence or resumption of USB bus activity */ 
		sx2EnumOK		= FALSE;	/* false until ENUMOK interrupt */ 
		sx2EP0Buf		= FALSE;	/* false until EP0BUF interrupt */ 
		sx2Setup		= FALSE;	/* false until SETUP interrupt */ 
		 
		/* Initialize global variables specific to this test firmware */ 
		keepAliveCnt		= 0; 
 
		/* Initialize local variables */ 
		/* reusable variable for read register data */ 
		regValue			= 0; 
		if(!Load_descriptors(DESCTBL_LEN, &desctbl[0])) 
		{ 
			while(TRUE); 
		} 
		 
		/*装载描述表后,等待自举成功*/ 
		while(sx2EnumOK == FALSE);  
 
		/*设置当前的接口的形式*/ 
		Write_SX2reg(SX2_IFCONFIG , 0xE8); 
		/*设置当前系统中各使能信号的极性 
		  其中SLOE、SLRD、SLWR只能有EEPROM来配置*/ 
		Write_SX2reg(SX2_FIFOPOLAR, SX2_WUPOL | SX2_EF | SX2_FF); 
		/*读取当前工作在哪个USB的标准*/ 
		Read_SX2reg(SX2_FNADDR, &Usb2or11); 
		hshostlink = (Usb2or11 & SX2_HSGRANT) ? TRUE : FALSE; 
		/*初始化USB的工作状态*/ 
		if(hshostlink ==TRUE) 
		{ 
			/*工作在2.00标准,设定数字接口为16位,数据包的大小为512字节*/ 
			Fifolong = 0x100; 
			Write_SX2reg(SX2_EP2PKTLENH , SX2_WORDWIDE | 0x02); 
			Write_SX2reg(SX2_EP2PKTLENL , 0x00); 
			Write_SX2reg(SX2_EP4PKTLENH , SX2_WORDWIDE | 0x02); 
			Write_SX2reg(SX2_EP4PKTLENL , 0x00); 
			Write_SX2reg(SX2_EP6PKTLENH , SX2_WORDWIDE | 0x02); 
			Write_SX2reg(SX2_EP6PKTLENL , 0x00); 
			Write_SX2reg(SX2_EP8PKTLENH , SX2_WORDWIDE | 0x02); 
			Write_SX2reg(SX2_EP8PKTLENL , 0x00); 
		} 
		else 
		{ 
			/*工作在1.1标准,设定数字接口为16位,数据包的大小为64字节*/ 
			Fifolong =0x20; 
			Write_SX2reg(SX2_EP2PKTLENH , SX2_WORDWIDE); 
			Write_SX2reg(SX2_EP2PKTLENL , 0x40); 
			Write_SX2reg(SX2_EP4PKTLENH , SX2_WORDWIDE); 
			Write_SX2reg(SX2_EP4PKTLENL , 0x40); 
			Write_SX2reg(SX2_EP6PKTLENH , SX2_WORDWIDE); 
			Write_SX2reg(SX2_EP6PKTLENL , 0x40); 
			Write_SX2reg(SX2_EP8PKTLENH , SX2_WORDWIDE); 
			Write_SX2reg(SX2_EP8PKTLENL , 0x40); 
		} 
		/*设置FLAGSA为FIFO6的空的标志位; 
		  设置FLAGSB为FIFO8的空的标志位; 
		  FLAGSC与FLAGSD的状态为默认的状态*/ 
		Write_SX2reg(SX2_FLAGAB , SX2_FLAGA_FF6 | SX2_FLAGB_FF8);  
		/*清空所有的节点*/ 
		Write_SX2reg(SX2_INPKTEND, SX2_CLEARALL); 
		Read_SX2reg(SX2_EP68FLAGS, &FifoStatus68); 
			 
		/*自举后进行主程序的循环*/ 
		while(sx2EnumOK) 
		{ 
		   	/*读FIFO状态*/ 
			if(FLAGS_READ) 
			{ 
				FLAGS_READ = FALSE; 
				/*FIFO24状态的读取*/ 
					if(Read_SX2reg(SX2_EP24FLAGS, &FifoStatus24)) 
					{ 
						/*确定是否有FIFO满*/ 
						Fifostatus = FifoStatus24; 
						if(!(Fifostatus & SX2_EP2EF)) 
						{ 
							RecievedDataLongth = Fifolong; 
							for(i = 0;i 0 || setupBuff[7] > 0) 
							{	 
								/*等待EP0数据包准备好的标志*/ 
								while(!sx2EP0Buf); 
								/* 清除EP0数据包准备好的标志*/ 
								sx2EP0Buf = FALSE; 
								/*读数据相的数据长度*/ 
								Read_SX2reg(SX2_EP0BC, &endpoint0count); 
								/*读数据相的数据*/ 
								for(i = 0; i 0 || setupBuff[7] > 0) 
								{ 
									/*等待EP0数据包准备好的标志*/ 
									while(!sx2EP0Buf); 
									/* 清除EP0数据包准备好的标志*/ 
									sx2EP0Buf = FALSE; 
									/* write the data to the EP0 data buffer */ 
									Write_SX2reg(SX2_EP0BUF, regValue); 
 
								   /* write the byte count so the SX2 sends one byte; */ 
								   /* ignore requests for more than one byte  */ 
									Write_SX2reg(SX2_EP0BC, 1); 
								} 
								else 
								{ 
									/*无数据相*/ 
									Write_SX2reg(SX2_EP0BC, 0); 
								} 
								break; 
							 
							default: 
								/* unsupported request */ 
								/* write any non-zero value to the setup register 
						   		to stall the request. */ 
								Write_SX2reg(SX2_SETUP, 0xff); 
							break; 
						} 
					} 
					else 
					{ 
						/*不支持的请求,写非零数到SX2_SETUP,取消此请求*/ 
						Write_SX2reg(SX2_SETUP, 0xff); 
					}			 
				}/*解析IN类型的命令申请*/						 
			}/*关于setup中断的处理*/ 
		}/*自举后进行主程序的循环*/ 
	} 
}  
 
BOOL Load_descriptors(char length, char* desc) 
{ 
	unsigned char i; 
	/* write LSB of descriptor length,and the address of the Descriptor */ 
	if(!Write_SX2reg(SX2_DESC, (unsigned int)length)) 
	{ 
		return FALSE; 
	} 
 
	/* write high nibble of MSB of descriptor length */ 
	SX2_comwritebyte((unsigned char)(length >> 12)); 
 
	/* write low nibble of MSB of descriptor length */ 
	SX2_comwritebyte((unsigned char)((length & 0x0F00)>>8)); 
	 
	for(i=0; i> 4)); 
		/* write low nibble of MSB of descriptor length */ 
		SX2_comwritebyte((desc[i] & 0x0F)); 
	} 
 
	return TRUE; 
} 
 
/**********************************************************************************/ 
/*	Function: Write_SX2reg														  */ 
/*	Purpose:  Writes to a SX2 register											  */ 
/*	Input:	  addr  - address of register										  */ 
/*			  value - value to write to address									  */ 
/*	Output:	  TRUE  on success													  */ 
/*			  FALSE on failure													  */ 
/**********************************************************************************/ 
BOOL Write_SX2reg(unsigned char addr, unsigned int value) 
{ 
	unsigned int transovertime = 0 ; 
	/*clear the high two bit of the addr*/ 
	addr = addr & 0x3f; 
	/* write register address to the SX2 */ 
	if(!SX2_comwritebyte(0x80 | addr)) 
	{ 
		return FALSE; 
	} 
	/* write high nibble of register data */ 
	SX2_comwritebyte((value >> 4) & 0xF); 
	/* write low nibble of register data */ 
	SX2_comwritebyte(value & 0x0F); 
	/*wait the ready is ok*/ 
	transovertime = 0; 
	while((*USB_STS & 0x08) == 0 ) 
	{ 
		if( transovertime++ > usbtimeout ) 
		{ 
			return FALSE; 
		} 
	} 
	/*the write is ok*/ 
	return TRUE; 
} 
 
/**********************************************************************************/ 
/*	Function: SX2_comwritebyte													  */ 
/*	Purpose:  Writes to a SX2 command interface									  */ 
/*	Input:	  value - value to write to address									  */ 
/*	Output:	  TRUE  on success													  */ 
/*			  FALSE on failure													  */ 
/**********************************************************************************/ 
BOOL SX2_comwritebyte(unsigned int value) 
{ 
	unsigned int time_count = 0; 
	/*wait the ready is ok*/ 
	while((*USB_STS & 0x08) ==0 ) 
	{ 
		if( time_count++ > usbtimeout ) 
		{ 
			return FALSE; 
		} 
	} 
	*USB_COMMAND = value; 
	/*the write is ok*/ 
	return TRUE; 
} 
 
/********************************************************** 
* 
*	Function: Read_SX2reg 
*	Purpose:  Reads a SX2 register 
*	Input:	  addr  - address of register 
*			  value - value read from register 
*	Output:	  TRUE  on success 
*			  FALSE on failure 
* 
**********************************************************/ 
 
BOOL Read_SX2reg(unsigned char addr, unsigned int *value) 
{ 
	unsigned int transovertime = 0; 
	/*READY是否准备好,延时时间到,返回*/ 
	while((*USB_STS & 0x08) == 0 ) 
	{ 
		if( transovertime++ > usbtimeout ) 
		{ 
			return FALSE; 
		} 
	} 
	/*clear the high two bit of the addr*/ 
	addr = addr & 0x3f; 
	/* write 'read register' command to SX2 */ 
	*USB_COMMAND = 0xC0 | addr; 
 
	/* set read flag to indicate to the interrupt routine that we 
	   are expecting an interrupt to read back the contents of the 
	   addressed register. The interrupt latency of the SX2 is in 
	   tens of microseconds, so it's safe to write this flag after 
	   the initial 'read' byte is written.  */ 
	/*设置读标志,通知中断程序不做处理读中断,只要返回标志为假就可以了*/ 
	readFlag = TRUE; 
 
	/* wait for read flag to be cleared by an interrupt */ 
	/*等待读标志为假*/ 
	while(readFlag); 
	 
	/*wait the ready is ok*/ 
	while((*USB_STS & 0x08) == 0 ) 
	{ 
		if( transovertime++ > usbtimeout ) 
		{ 
			return FALSE; 
		} 
	} 
	/*读取寄存器的数据*/ 
	*value = *USB_COMMAND; 
	return TRUE; 
} 
 
/*********************************************************/ 
/*                                                       */ 
/*	Function: SX2_FifoWrite                              */ 
/*	Purpose:  write buffer to sx2fifo                    */ 
/*	Input:	  channel,the endpoint you select			 */ 
/*			  pdata - the pointer to databuffer			 */ 
/*			  longth - the longth of the databuffer      */ 
/*	Output:	  TRUE  on success                           */ 
/*			  FALSE on failure							 */ 
/*														 */ 
/*********************************************************/ 
 
BOOL SX2_FifoWrite(int channel,unsigned int *pdata,unsigned length) 
{ 
	unsigned int i = 0; 
		if(channel == ENDPOINT2) 
		{ 
			for(i = 0;i 7) 
			{ 
				setupDat = FALSE; 
				sx2Setup = TRUE; 
			} 
			else 
			{ 
				*USB_COMMAND = 0xC0 | SX2_SETUP; 
			} 
	     	} 
		    /* if this is a new request, then we have to read the 
		 value and parse the interrupt value. The value  
		 can't be parsed in the main loop, otherwise we could 
		 get two interrupts back to back and trash the first  
		 one in the series. */ 
		 else 
		 { 
			/* read the interrupt register value */ 
			irqValue = *USB_COMMAND; 
 
			switch(irqValue) 
			{ 
				case SX2_INT_SETUP: 
					/* endpoint 0 setup */ 
					/* next eight interrupts are setup data */ 
					/* parse the interrupt register value */		 
					setupDat = TRUE;			 
					setupCnt = 0; 
					/* send read register command to SX2 */ 
					*USB_COMMAND = 0xC0 | SX2_SETUP; 
					break; 
		 
				case SX2_INT_EP0BUF: 
					/* endpoint 0 ready */ 
					sx2EP0Buf = TRUE; 
					break; 
		 
				case SX2_INT_FLAGS: 
					/* FIFO flags -FF,PF,EF */ 
					FLAGS_READ = TRUE; 
					break; 
		 
				case SX2_INT_ENUMOK: 
					/* enumeration successful */ 
					sx2EnumOK = TRUE; 
					break; 
		 
				case SX2_INT_BUSACTIVITY: 
					/* detected either an absence or resumption of activity on the USB bus.	 */ 
					/* Indicates that the host is either suspending or resuming or that a 	 */ 
					/* self-powered device has been plugged into or unplugged from the USB.	 */ 
					/* If the SX2 is bus-powered, the host processor should put the SX2 into */  
					/* a low-power mode after detecting a USB suspend condition.			 */ 
					sx2BusActivity = TRUE; 
					break; 
				case SX2_INT_READY: 
					/* awakened from low power mode via wakeup pin */ 
					/* or completed power on self test */ 
					sx2Ready = TRUE; 
					break; 
		 
				default: 
					break; 
			} 
	  	} 
	PieCtrl.PIEACK.bit.ACK1 = 1; 
	EINT; 
}