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

📄 dec5502_usb.c

📁 数字信号处理中的USB接口程序,希望对大家有用处
💻 C
字号:

/***************************************************
File:    DEC5502_USB.c
Author:  Lifeng Duan
Created: 8/21/2004

Description:Evaluates the use of SX2 with DSP

Copyright (C) SEED SEMICONDUCTOR, 2004
*****************************************************/
#include <csl.h>
#include <csl_pll.h>
#include <csl_irq.h>
#include <csl_dma.h>
#include <csl_i2c.h>
#include <csl_mcbsp.h>
#include <csl_gpt.h>
#include "emif.h"
#include "i2c.h"
#include "mcbsp.h"
#include "cslconfig.h"
#include "codec.h"
#include "timer.h"

#include "type.h"
#include "descriptors.h"
#include "sysreg.h"
#include "sx2.h"
#include "ep0Req.h"
#include "E2PROM_Function.h"

#define decintreg  0x2
#define USBINT 0x10

void delay();

/* global variables */
extern BYTE irqValue;			 /* interrupt register value */
extern BYTE setupBuff[8];		 /* setup transaction buffer */
extern BOOL sx2Ready;			 /* status byte for POST */ 
extern BOOL sx2BusActivity;	 	 /* status byte for suspend */ 
extern BOOL sx2EnumOK;			 /* status byte for enumeration complete */
extern BOOL sx2EP0Buf;			 /* status for endpoint 0 buffer */
extern BOOL sx2Setup;			 /* setup flag set in Int0() ISR */
extern BOOL readFlag;
extern BOOL FLAGS_READ;          /* FIFO的状态读请求*/

 unsigned int MYMARK;
 unsigned int FIFOMARK;
 
/* global variables specific to this test firmware */
unsigned int FifoWriteCnt ;
unsigned int epdatar[512] ;
unsigned int epdataw[512] ;
unsigned int epdataw1[256];

/* MCBSP接收缓冲区 */
#pragma DATA_SECTION(codecdat,".codec_buffer")
unsigned int codecdat[0x400];

unsigned int CodecReceivData[2];

void main()
{
	unsigned int regValue = 0;	 		/*  register value from a read 	*/
	unsigned int Sx2int = 0;     		/*	SX2的中断状态 				*/
	unsigned int Usb2or11= 0;    		/*	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;		/* FIFO的状态标志 	*/
	unsigned int Fifolong = 0;     		/* FIFO的长度 		*/
	BOOL hshostlink = False; 			/* 为真是高速USB接口,为假是低速USB接口 */
	BOOL codec_runing = False;
	unsigned int RecievedDataLongth = 0;
	unsigned int DataToEndpoint0 = 0;	/* 写入到Endpoint0的数据缓冲 */
	
	/* 初始化CSL库,配置USB和定时器中断 */
	Csl_Config();
 	
 	/* 设置系统的运行速度为240MHz */
    PLL_setFreq(1, 0xc, 0, 1, 3, 3, 0);
    
	/* 配置I2C */
	I2c_Setup();
    
    /* 配置EMIF为全EMIF接口并初始化DSP的外部EMIF */
    Emif_Config(); 
    
    /* 配置MCBSP */
    Mcbsp_Config();
    
    /* 配置定时器 */
    Config_timer();
    
    /* 配置指示灯D5 */
    Config_led();
    
	/* 初始化CODEC数据 */       		
	for(i = 0;i<0x200;i++)
	{
		codecdat[i] = 0;
	}
	
	/*判断CY68001是否准备好*/
	for(;;)
	{    
		/*判断是否有中断到来*/
		regValue = SYSSTAT1;
		if((regValue & USBINT) == 0)
		{
		  /*判断是何种中断,并清中断*/
		  Sx2int = USB_Command_Read();
		  if(Sx2int &(SX2_INT_ENUMOK + SX2_INT_READY))
		  {  
		    /*打开系统的串口中断*/
		      SysInt_Enable();		
		      break;  
		  }  
	  	}
	  	else
	  	{	
	   		/*打开系统的串口中断*/
			SysInt_Enable();
			break;  
	  	}
	}
	/*自举循环*/	
	while(True)
	{
		/* 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 */
		MYMARK = 0;
		FIFOMARK = 0;
		
		/* Initialize local variables */
		/* reusable variable for read register data */
		regValue = 0;
		
		/* load descriptor tables; halt if load fails */
		if(!Load_descriptors(DESCTBL_LEN, &desctbl[0]))
		{
			while(True);
		}
	
		/*装载描述表后,等待自举成功*/
		while( !MYMARK )
		{
			MYMARK = sx2EnumOK;
		}
				
		/*设置当前的接口的形式*/
		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)
		{
			/*CODEC CIRCLE运行*/
			if(codec_runing == True)
			{
				Receiv_data(CodecReceivData);
				Trans_data(CodecReceivData);
			}/*CODEC CIRCLE运行*/
			/*读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<Fifolong;i++)
						{
							epdatar[i] = SX2_FifoReadSingle(ENDPOINT2);
						}
						SX2_FifoWrite(ENDPOINT6,&epdatar[0],Fifolong);
						
						/*小于整数据包的数据提交SX2发送给主机*/
						if(RecievedDataLongth<(Fifolong-1))
						{
							Write_SX2reg(SX2_INPKTEND, 0x06);	
						}
					}
					
					Fifostatus = FifoStatus24;
					if(!(Fifostatus & SX2_EP4EF))
					{   
						RecievedDataLongth = Fifolong;
						   
						for(i = 0;i<Fifolong;i++)
						{
							epdatar[i] = SX2_FifoReadSingle(ENDPOINT4);
						}
						SX2_FifoWrite(ENDPOINT8,&epdatar[0],Fifolong);
						
						/*小于整数据包的数据提交SX2发送给主机*/
						if(RecievedDataLongth<(Fifolong-1))
						{
							Write_SX2reg(SX2_INPKTEND, 0x08);	
						}	
					}	
				}/*FIFO24状态的读取*/
				/*FIFO68状态的读取*/
				if(Read_SX2reg(SX2_EP68FLAGS, &FifoStatus68))
				{
					/*无操作,可由用户测试使用*/		
				}	
			}/*读FIFO状态*/
			
			/*关于setup中断的处理*/
			if(sx2Setup)
			{
				/*清SETUP数据读的标志*/
				sx2Setup = False;
				
				/*解析OUT类型的命令申请*/
				if(setupBuff[0] == VR_TYPE_OUT)
				{
					/*分析命令类型*/
					switch(setupBuff[1])
					{	
						/*系统复位*/
						case VR_RESET:
							/*写0到EP0的计数寄存器,结束本次控制握手*/
							Write_SX2reg(SX2_EP0BC, 0);
							break;
						/*读命令*/
						case VR_BULK_READ:
							/*写0到EP0的计数寄存器,结束本次控制握手*/
							Write_SX2reg(SX2_EP0BC, 0);
							break;
						/*写操作*/	
						case VR_BULK_WRITE:
							/*清空节点6与8*/
							switch (setupBuff[2])
							{
								case ENDPOINT6:
									/*写入节点6*/
									for(i = 0;i<0x100;i++)
									{
										epdataw1[i] = i*2;	
									}
									for(i = 0;i<0x50;i=i+2)
									{
										epdataw[i/2] = epdataw1[i]+(epdataw1[i+1]<<8);
									}
									
									/*如果发送小于整数据包的数据时,设置RecievedDataLongth*/
									RecievedDataLongth = 0x3f;
									
									/*读当前FIFO的状态,是否已满*/
									regValue = sysreg_read(sysstat0);
									
									FifoWriteCnt = 0;
									SX2_FifoWrite(ENDPOINT6,&epdataw[0],Fifolong);
									setupBuff[1] = 0;
									
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
								case  ENDPOINT8:
									/*写入节点6*/
									for(i = 0;i<0x200;i++)
									{
										epdataw1[i] = i*2+1;
									}
									for(i = 0;i<0x50;i=i+2)
									{
										epdataw[i/2] = epdataw1[i]+(epdataw1[i+1]<<8);
									}
									i = 0;
									/*如果发送小于整数据包的数据时,设置RecievedDataLongth*/
									RecievedDataLongth = 0x1f;
									
									/*读当前FIFO的状态,是否已满*/
									regValue = sysreg_read(sysstat0);
								
									SX2_FifoWrite(ENDPOINT8,&epdataw[0],Fifolong);
									setupBuff[1] = 0;
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
								default:
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;	
							}	
							break;
						/*LED灯D5的操作*/	
						case VR_LED_OPTION:
							switch(setupBuff[2])
							{
								case LED_ON:
									/*点亮LED*/
									Timer_stop();
									Open_led();
									
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
								case LED_OFF:
									/*关掉LED*/
									Timer_stop();
									Close_led();
									
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
								case LED_BLINK:
									/*使D5闪烁*/
									Timer_start();
									
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
								default:
									/*写0到EP0的计数寄存器,结束本次控制握手*/
									Write_SX2reg(SX2_EP0BC, 0);
									break;
							}
							break;
						/*CODEC 试听*/
						case VR_CODEC_CIRCLE:
							I2c_Setup();
							codec_runing = True;
							Open_Codec();		// 打开Codec
							
							/*写0到EP0的计数寄存器,结束本次控制握手*/
							Write_SX2reg(SX2_EP0BC, 0);
							break;
						case VR_CODEC_HALT:
							codec_runing = False;
							Close_Codec();		// 关闭Codec
							
							Write_SX2reg(SX2_INPKTEND, SX2_CLEARALL);
							
							/*写0到EP0的计数寄存器,结束本次控制握手*/
							Write_SX2reg(SX2_EP0BC, 0);
							break;
						/*Endpoint0内容的读操作*/	
						case VR_ENDPOINT0READ:
							/*确定Endpoint0的长度*/
							if (setupBuff[6] > 0 || setupBuff[7] > 0)
							{	
								/*等待EP0数据包准备好的标志*/
								while(!sx2EP0Buf);
								
								/* 清除EP0数据包准备好的标志*/
								sx2EP0Buf = False;
								
								/*读数据相的数据长度*/
								Read_SX2reg(SX2_EP0BC, &endpoint0count);
								
								/*读数据相的数据*/
								for(i = 0; i<endpoint0count;i++)
								{
									Read_SX2reg(SX2_EP0BUF,&endpoint0data[i]);
								}
							}
							break;
						
						case VR_REGWRITE:
							/* write the actual value to the register */
							Write_SX2reg(setupBuff[4], setupBuff[2]);
							
							/*写0到EP0的计数寄存器,结束本次控制握手*/
							Write_SX2reg(SX2_EP0BC, 0);
							break;

						default:
							/*不支持的请求*/
							/*写非零数到SX2_SETUP,取消此请求*/
							Write_SX2reg(SX2_SETUP, 0xff);
							break;	
					}/*分析命令类型*/
				}
				else
				{
					/*解析IN类型的命令申请*/
					if(setupBuff[0] == VR_TYPE_IN)
					{
						/*分析命令类型*/
						switch(setupBuff[1])
						{
							
							/*USB工作的标准*/
							case VR_USB_VERION:
								if(hshostlink ==True)
								{
									DataToEndpoint0 = 0x55;
								}
								else
								{
									DataToEndpoint0 = 0x54;
								}
								Write_SX2reg(SX2_EP0BUF, DataToEndpoint0);
								
								/*写入要传回的数据的长度*/
								Write_SX2reg(SX2_EP0BC, 1);
								break;
							
							/* SX2REGRD request */
							case VR_REGREAD:
								/* read the requested register */									
								Read_SX2reg(setupBuff[4], &regValue);
								break;
							
							case VR_ENDPOINT0WRITE:
								/*确定是否有数据相*/
								if (setupBuff[6] > 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中断的处理*/
		}/*自举后进行主程序的循环*/
	}/*自举循环*/
}

/* 指示灯XF打开和关闭的时间长度 */
void delay(void)
{
	int j = 0;
	int i = 0;
	for(i = 0; i <0x80;i++)
	{
		for(j = 0;j<0xfffe;j++)
		{
			asm(" NOP");
		}	
	}
}

/******************************************************************************************/
//	No 	more
/******************************************************************************************/

⌨️ 快捷键说明

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