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

📄 usb.c

📁 基于TI 6416DSP 的USB读写程序
💻 C
字号:
/**************************************************************************************
	filename:	USB.C
	designer:	戴展波
	date:		2004/11/01
***************************************************************************************/

#include <stdio.h>
#include <csl.h>
#include <csl_irq.h>
#include <csl_chip.h>
#include <csl_gpio.h>
#include <csl_emifb.h>

#include "USB.h"
#include "descriptor.h"
#include "USB_CONSTANT.h"
#include "endpoint0_request.h"

static Uint32 gpgc = GPIO_GPGC_RMK(
	GPIO_GPGC_GP0M_GPIOMODE,
	GPIO_GPGC_GPINT0M_DEFAULT,
	GPIO_GPGC_GPINTPOL_DEFAULT,
	GPIO_GPGC_LOGIC_DEFAULT,
	GPIO_GPGC_GPINTDV_DEFAULT
);

static Uint32 gpen = GPIO_GPEN_OF(0x7620);
static Uint32 gpdir = GPIO_GPDIR_OF(0x0200);
static Uint32 gpval = GPIO_GPVAL_OF(0x0200);
static Uint32 gphm = GPIO_GPHM_RMK(GPIO_GPHM_GPXHM_DEFAULT);
static Uint32 gplm = GPIO_GPLM_RMK(GPIO_GPLM_GPXLM_DEFAULT);
static Uint32 gppol = GPIO_GPPOL_RMK(GPIO_GPPOL_GPINTXPOL_OF(0x20));

GPIO_Handle hGpio;

static EMIFB_Config MyEmifbConfig = 
{
	EMIFB_GBLCTL_RMK
	(
		EMIFB_GBLCTL_EK2RATE_FULLCLK,	//1 X EMIF input clock
		EMIFB_GBLCTL_EK2HZ_CLK,		//eclkout2 continue output during hold
		EMIFB_GBLCTL_EK2EN_ENABLE,	//eclkout2 enable output
		EMIFB_GBLCTL_BRMODE_MRSTATUS,	//bus request is memory access or refresh pending/in progress
		EMIFB_GBLCTL_NOHOLD_ENABLE,
		EMIFB_GBLCTL_EK1HZ_CLK,		//eclkout1 continue output during hold
		EMIFB_GBLCTL_EK1EN_ENABLE	//eclkout1 enable output
	),
	0x22a28a22,
	0x20a0c412,
	0x22a28a22,
	0x3373cd1f,		//clk/4
//	0x2232c81f,		//clk/6
	EMIFB_SDCTL_DEFAULT,
	EMIFB_SDTIM_DEFAULT,
	EMIFB_SDEXT_DEFAULT,
	0x00000002,
	0x00000002,
	0x00000002,
	0x00000002
};

GPIO_Handle hGpio;

void main(void)
{
	unsigned int i;
	//初始化CSL库
	CSL_init();
	//关总中断
	IRQ_globalDisable();
	//打开GPIO句柄
	hGpio = GPIO_open(GPIO_DEV0,GPIO_OPEN_RESET);
	//GPIO配置
	GPIO_configArgs(hGpio,gpgc,gpen,gpdir,gpval,gphm,gplm,gppol);
	//EMIFB配置
	EMIFB_config(&MyEmifbConfig);
	//设置中断矢量表地址
	IRQ_setVecs(vectors);
	//设置中断通道
	IRQ_map(IRQ_EVT_EXTINT5,5);
	//中断使能
	IRQ_enable(IRQ_EVT_EXTINT5);
	//NMI使能
    	IRQ_nmiEnable();
    	//开总中断
    	IRQ_globalEnable();
	//判断是否有USB中断
	USB_interruptClear();
	//初始化USB参数
	USB_variableInit();
	//usb自举
	if(load_descriptor(DESCTBL_LEN,&desc_table[0]) == FALSE)
	{
		//fail
		for(;;);
	}
	do{
	}while(sx2EnumOK == FALSE);
	/*设置当前的接口的形式*/
	Write_Register(SX2_IFCONFIG,SX2_IFCONFIG_SET);
	/*设置当前系统中各使能信号的极性
	其中SLOE、SLRD、SLWR只能有EEPROM来配置*/
	Write_Register(SX2_POLAR, SX2_POLAR_WUPOL | SX2_POLAR_EF | SX2_POLAR_FF);
	/*读取当前工作在哪个USB的标准*/
	Read_Register(SX2_FNADDR,&hshostlink);
	/*初始化USB的工作状态*/
	if((hshostlink & SX2_HSGRANT) == SX2_HSGRANT)
	{
		speed_flag = TRUE;
		//high speed,480M
		/*工作在2.00标准,设定数字接口为16位,数据包的大小为512字节*/
		Fifolong = 0x100;
		Write_Register(SX2_EP2PKTLENH,SX2_WORDWIDE|0x20);
		Write_Register(SX2_EP2PKTLENL,0x00);
		Write_Register(SX2_EP4PKTLENH,SX2_WORDWIDE|0x20);
		Write_Register(SX2_EP4PKTLENL,0x00);
		Write_Register(SX2_EP6PKTLENH,SX2_WORDWIDE|0x20);
		Write_Register(SX2_EP6PKTLENL,0x00);
		Write_Register(SX2_EP8PKTLENH,SX2_WORDWIDE|0x20);
		Write_Register(SX2_EP8PKTLENL,0x00);
	}
	else
	{
		speed_flag = FALSE;
		Fifolong = 0x20;
		Write_Register(SX2_EP2PKTLENH,SX2_WORDWIDE);
		Write_Register(SX2_EP2PKTLENL,0x40);
		Write_Register(SX2_EP4PKTLENH,SX2_WORDWIDE);
		Write_Register(SX2_EP4PKTLENL,0x40);
		Write_Register(SX2_EP6PKTLENH,SX2_WORDWIDE);
		Write_Register(SX2_EP6PKTLENL,0x40);
		Write_Register(SX2_EP8PKTLENH,SX2_WORDWIDE);
		Write_Register(SX2_EP8PKTLENL,0x40);
	}
	/*设置FLAGSA为FIFO6的空的标志位;
	设置FLAGSB为FIFO8的空的标志位;
	FLAGSC与FLAGSD的状态为默认的状态*/
	Write_Register(SX2_FLAGSAB,SX2_FLAGA_FF6 | SX2_FLAGB_FF8);
	/*清空所有FIFO*/
	Write_Register(SX2_INPKTEND,SX2_CLEARALL);
	/*读FIFO68的状态*/
	Read_Register(SX2_EP68FLAGS, &FifoStatus68);
	for(;;)
	{
		if(FLAGS_READ == TRUE)
		{
			FLAGS_READ = FALSE;
			if(Read_Register(SX2_EP24FLAGS,&FifoStatus24) == TRUE)
			{
				FifoStatus = FifoStatus24;
				/*确定是否有FIFO满*/
				if((FifoStatus & SX2_EP2EF) != SX2_EP2EF)
				{
					for(i = 0; i < Fifolong; i++)
					{
						fifo_data[i] = USB_FIFOReadSingle(ENDPOINT2);
					}
					USB_FIFOWrite(ENDPOINT6,&fifo_data[0],Fifolong);
					Write_Register(SX2_INPKTEND,0x06);
					/*写0到EP0的计数寄存器,结束本次控制握手*/
					Write_Register(SX2_EP0BC, 0);
				}
				if((FifoStatus & SX2_EP4EF) != SX2_EP4EF)
				{
					for(i = 0; i < Fifolong; i++)
					{
						fifo_data[i] = USB_FIFOReadSingle(ENDPOINT4);
					}
					USB_FIFOWrite(ENDPOINT8,&fifo_data[0],Fifolong);
					Write_Register(SX2_INPKTEND,0x08);
					/*写0到EP0的计数寄存器,结束本次控制握手*/
					Write_Register(SX2_EP0BC, 0);
				}
			}
		}
		/*关于setup中断的处理*/
		if(sx2Setup == TRUE)
		{
			sx2Setup = FALSE;
			/*解析OUT类型的命令申请*/
			if(setupBuff[0] == VR_TYPE_OUT)
			{
				/*分析命令类型*/
				switch(setupBuff[1])
				{
				/*系统复位*/
				case VR_RESET:
					/*写0到EP0的计数寄存器,结束本次控制握手*/
					Write_Register(SX2_EP0BC, 0);
					break;
				
				/*读命令*/	
				case VR_BULK_READ:
					/*写0到EP0的计数寄存器,结束本次控制握手*/
					Write_Register(SX2_EP0BC, 0);
					break;
					
				/*写操作*/
				case VR_BULK_WRITE:
					/*清空节点6与8*/
					switch(setupBuff[2])
					{
					case ENDPOINT6:
						/*写入节点6*/
						for(i = 0; i < 0x100; i++)
						{
							fifo_data1[i] = 2 * i;
						}
						for(i = 0;i<0x50;i=i+2)
						{
							fifo_data[i/2] = fifo_data1[i]+(fifo_data1[i+1]<<8);
						}
						USB_FIFOWrite(ENDPOINT6,&fifo_data[0],Fifolong);
						Write_Register(SX2_INPKTEND,0x06);
						/*写0到EP0的计数寄存器,结束本次控制握手*/
						Write_Register(SX2_EP0BC, 0);
						break;
						
					case ENDPOINT8:
						/*写入节点6*/
						for(i = 0; i < 0x200; i++)
						{
							fifo_data1[i] = 2 * i + 1;
						}
						for(i = 0;i<0x50;i=i+2)
						{
							fifo_data[i/2] = fifo_data1[i]+(fifo_data1[i+1]<<8);
						}
						USB_FIFOWrite(ENDPOINT8,&fifo_data[0],Fifolong);
						Write_Register(SX2_INPKTEND,0x08);
						/*写0到EP0的计数寄存器,结束本次控制握手*/
						Write_Register(SX2_EP0BC, 0);
						break;
						
					default:
						Write_Register(SX2_EP0BC, 0);
						break;
					}
					
				/*Endpoint0内容的读操作*/	
				case VR_ENDPOINT0READ:
					/*确定Endpoint0的长度*/
					if (setupBuff[6] > 0 || setupBuff[7] > 0)
					{
						/*等待EP0数据包准备好的标志*/
						while(!sx2EP0Buf);
						/**/
						sx2EP0Buf = FALSE;
						/*读数据相的数据长度*/
						Read_Register(SX2_EP0BC,&endpoint0count);
						for(i = 0; i < endpoint0count; i++)
						{
							Read_Register(SX2_EP0BUF,&endpoint0data[i]);
						}
					}
					break;
					
				case VR_REGWRITE:
					/* write the actual value to the register */
					Write_Register(setupBuff[4], setupBuff[2]);
					/*写0到EP0的计数寄存器,结束本次控制握手*/
					Write_Register(SX2_EP0BC, 0);
					break;
				
				default:
					Write_Register(SX2_SETUP,0xff);
					break;
				}
			}

			/*解析IN类型的命令申请*/
			else if(setupBuff[0] == VR_TYPE_IN)
			{
				/*分析命令类型*/
				switch(setupBuff[1])
				{
				/*USB工作的标准*/
				case VR_USB_VERION:
					if(speed_flag == TRUE)
					{
						DataToEndpoint0 = 0x55;
					}
					else
					{
						DataToEndpoint0 = 0xaa;
					}
					/*应答IN SETUP包的请求*/
					Write_Register(SX2_EP0BUF,DataToEndpoint0);
					/*写入要传回的数据的长度*/
					Write_Register(SX2_EP0BC,1);
					break;
				
				/* SX2REGRD request */	
				case VR_REGREAD:
					Read_Register(setupBuff[4], &regValue);
					break;
					
				/**/
				case VR_ENDPOINT0WRITE:
					/*确定是否有数据相*/
					if (setupBuff[6] > 0 || setupBuff[7] > 0)
					{
						/*等待EP0数据包准备好的标志*/
						while(!sx2EP0Buf);
						/* 清除EP0数据包准备好的标志*/
						sx2EP0Buf = 0;
						/* write the data to the EP0 data buffer */
						Write_Register(SX2_EP0BUF, regValue);
						/*写入要传回的数据的长度*/
						Write_Register(SX2_EP0BC, 1);
					}
					else
					{
						/*写入要传回的数据的长度*/
						Write_Register(SX2_EP0BC, 0);
					}
					break;
				
				default:
					//取消这次请求
					Write_Register(SX2_SETUP,0xff);
					break;
				}
			}
			else
			{
				Write_Register(SX2_SETUP,0xff);
			}
		}
	}
	
}

/* 初始化USB的参数 */
void USB_variableInit(void)
{
	readFlag = FALSE;
	setupCnt = 0;
	sx2EP0Buf = FALSE;
	sx2EnumOK = FALSE;
	sx2BusActivity = FALSE;
	sx2Ready = FALSE;
	sx2Setup = FALSE;
}

/* 判断是否有中断产生 */
void USB_interruptClear(void)
{
	while(1)
	{
		if(GPIO_pinRead(hGpio,GPIO_PIN5) == 0)	//有USB中断
		{
			//读USB中断寄存器的值
			SX2_int = *USB_COMMAND & (SX2_INT_ENUMOK + SX2_INT_READY);
			if(SX2_int != FALSE)
			{
				break;
			}
		}
		else
		{
			break;
		}
	}
}

/* 自举 */
unsigned int load_descriptor(unsigned int length,unsigned char* desc)
{
	unsigned int i;
	/*1、初始化写请求对0x30*/
	/*2、写2个BYTE的自举表长度,4个写命令,先LSB*/
	/*3、写自举表*/
	if(Write_Register(SX2_DESC,length) == FALSE)
	{
		return FALSE;
	}
	
	if(Write_Byte(length>>12) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	if(Write_Byte(length>>8) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	for(i = 0; i < length; i++)
	{
		if(Write_Byte(desc_table[i]>>4) == FALSE)
		{
			return FALSE;
		}
		delay_time(1000);
		if(Write_Byte(desc_table[i]&0x0f) == FALSE)
		{
			return FALSE;
		}
		delay_time(1000);
	}
	return TRUE;
}

/* */
unsigned int Write_Register(unsigned char addr,unsigned int value)
{
	unsigned int timecount = 0;
	//清地址高2位
	addr = addr & 0x3f;
	/*判断READY信号是否为高*/
	while(GPIO_pinRead(hGpio,GPIO_PIN10) ==0 )
	{
		timecount++;
		if(timecount > usbtimeout)
		{
			return FALSE;
		}
	}
	//写寄存器地址
	if(Write_Byte(addr|0x80) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	//写数据1
	if(Write_Byte(value>>4) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	//写数据2
	if(Write_Byte(value&0x0f) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	return TRUE;
}

/* 读寄存器的值 */
unsigned int Read_Register(unsigned int addr,unsigned int *value)
{
	unsigned int timecount = 0;
	//清地址高2位
	addr = addr & 0x3f;
	//
	readFlag = 1;
	while(GPIO_pinRead(hGpio,GPIO_PIN10) == 0 )
	{
		timecount++;
		if(timecount > usbtimeout)
		{
			return FALSE;
		}
	}
	//写寄存器地址
	if(Write_Byte(addr|0xC0) == FALSE)
	{
		return FALSE;
	}
	delay_time(1000);
	//判断是否产生了读中断
	do{
	
	}while(readFlag == TRUE);
	//读寄存器的值
	if(Read_Byte() == FALSE)
	{
		return FALSE;
	}
	*value = read_value;
	return TRUE;
}

unsigned int Write_Byte(unsigned int value)
{
	unsigned int timecount = 0;
	/*判断READY信号是否为高*/
	while(GPIO_pinRead(hGpio,GPIO_PIN10) == 0 )
	{
		timecount++;
		if(timecount > usbtimeout)
		{
			return FALSE;
		}
	}
	//对USB的COMMAND口操作
	*USB_COMMAND = value;
	/**/
	return TRUE;
}

unsigned int Read_Byte(void)
{
	unsigned int timecount = 0;
	/*判断READY信号是否为高*/
	while(GPIO_pinRead(hGpio,GPIO_PIN10) ==0 )
	{
		timecount++;
		if(timecount > usbtimeout)
		{
			return FALSE;
		}
	}
	read_value = *USB_COMMAND;
	return TRUE;
}

unsigned int USB_FIFOWrite(unsigned int channel,unsigned int *data,unsigned int length)
{
	unsigned int i;
	switch(channel)
	{
		case ENDPOINT2:
			for(i = 0; i < length; i++)
			{
				*USB_FIFO2 = data[i];
				delay_time(1000);
			}
			break;
			
		case ENDPOINT4:
			for(i = 0; i < length; i++)
			{
				*USB_FIFO4 = data[i];
				delay_time(1000);
			}
			break;
			
		case ENDPOINT6:
			for(i = 0; i < length; i++)
			{
				*USB_FIFO6 = data[i];
				delay_time(1000);
			}
			break;
			
		case ENDPOINT8:
			for(i = 0; i < length; i++)
			{
				*USB_FIFO8 = data[i];
				delay_time(1000);
			}
			break;
			
		default:
			return FALSE;
	}
	return TRUE;
}

unsigned int USB_FIFOWriteSingle(unsigned int channel,unsigned int data)
{
	switch(channel)
	{
		case ENDPOINT2:
			*USB_FIFO2 = data;
			delay_time(1000);
			break;
			
		case ENDPOINT4:
			*USB_FIFO4 = data;
			delay_time(1000);
			break;
			
		case ENDPOINT6:
			*USB_FIFO6 = data;
			delay_time(1000);
			break;
			
		case ENDPOINT8:
			*USB_FIFO8 = data;
			delay_time(1000);
			break;
			
		default:
			return FALSE;
	}
	return TRUE;
}

unsigned int USB_FIFOReadSingle(unsigned int channel)
{
	unsigned int data;
	switch(channel)
	{
		case ENDPOINT2:
			data = *USB_FIFO2;
			delay_time(1000);
			break;
			
		case ENDPOINT4:
			data = *USB_FIFO4;
			delay_time(1000);
			break;
			
		case ENDPOINT6:
			data = *USB_FIFO6;
			delay_time(1000);
			break;
			
		case ENDPOINT8:
			data = *USB_FIFO8;
			delay_time(1000);
			break;
			
		default:
			break;
	}
	return data;
}

void delay_time(unsigned int value)
{
	unsigned int i;
	for(i = 0; i < value; i++);
}

interrupt void USB_INT(void)
{
	//当DSP发出一次读请求后,USB会产生一次读中断,在读中断后可以读寄存器的值
	if(readFlag == TRUE)
	{
		readFlag = FALSE;
	}
	//SETUP是USB中断一个很特别的例子,无论什么时候收到这个SETUP中断,后边的8个中断就是SETUP包
	else if(setupDat == TRUE)
	{
		setupBuff[setupCnt] = *USB_COMMAND;
		setupCnt++;
		if(setupCnt > 7)
		{
			setupDat = FALSE;
			sx2Setup = TRUE;
		}
		else
		{
			//对SETUP寄存器的读请求
			*USB_COMMAND = 0xC0|SX2_SETUP;
			delay_time(1000);
		}
	}
	//判断USB中断类型
	else
	{
		//读中断寄存器的值
		irqValue = *USB_COMMAND;
		switch(irqValue)
		{
			case SX2_INT_SETUP:
				setupCnt = 0;
				setupDat = TRUE;
				//对SETUP寄存器的读请求
				*USB_COMMAND = 0xC0|SX2_SETUP;
				delay_time(1000);
				break;
				
			case SX2_INT_EP0BUF:
				sx2EP0Buf = TRUE;
				break;
				
			case SX2_INT_FLAGS:
				FLAGS_READ = TRUE;
				break;
				
			case SX2_INT_ENUMOK:
				sx2EnumOK = TRUE;
				break;
				
			case SX2_INT_BUSACTIVITY:
				sx2BusActivity = TRUE;
				break;
				
			case SX2_INT_READY:
				sx2Ready = TRUE;
				break;
				
			default:
				break;
		}
	}
}

⌨️ 快捷键说明

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