📄 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], ®Value);
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 + -