?? 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 + -