www.pudn.com > adsample.rar > gpiflongxfr.c
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: gpiflongxfr.c
//
// Contents: Hooks required to implement USB peripheral function.
// Code written for EZUSB FX2 128-pin REVE...
// Firmware tested on EZUSB FX2 128-pin (CY3681 DK)
// Copyright (c) 2001 Cypress Semiconductor All rights reserved
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "fx2sdly.h" // SYNCDELAY macro
extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;
BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings
BOOL xfrvia_TD_Poll = 0; // Event flg for execution in TD_Poll( );
BOOL in_token_event = 0; // Event flg for GPIF FIFO Read trigger
// proto's from "gpif.c"
void GpifInit( void );
// it may be worth noting here that the default monitor loads at 0xC000
// use this global variable when (de)asserting debug LEDs...
// 512 for high speed, 64 for full speed
static WORD enum_pkt_size = 0x0000;
// when set firmware running in TD_Poll( ); handles data transfers
BOOL td_poll_handles_transfers = 0;
// when set cpu is out of the data path
BOOL endp_auto_mode_enabled = 0;
/////////////////////////////////////////////////////////////////////////
#define VX_A2 0xA2 // testing, GPIF single byte read waveform
#define VX_A3 0xA3 // testing, GPIF single byte write waveform
#define VX_A7 0xA7 // setup peripheral for high speed FIFO xfr(s), TC=8
#define VX_A8 0xA8 // do a FIFO Rd transaction w/TC=8 into EP8
#define VX_AC 0xAC // manually commit IN data to host... INPKTEND
#define VX_C5 0xC5 // for test purpose
#define VX_D0 0xD0 // read GPIFTCx registers
#define VX_D1 0xD1 // let TD_Poll( ); firmware handle data xfr's...
#define VX_D2 0xD2 // handle data xfr's via vendor specific cmds...
#define VX_EE 0xEE //reset address bus
/////////////////////////////////////////fiber manufaction command //////
#define VX_E0 0xE0 //握手
#define VX_E1 0xE1 //电子开关
#define VX_E2 0xE2 //电机行进
#define VX_E3 0xE3 //长周期光栅
#define VX_E4 0xE4 //电子开关,按存储器中延时数据制作布拉格光栅
#define VX_E5 0xE5 //数据传输初始化
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////define port
sbit O_STEP = IOA ^ 0;//PA.0电机步进脉冲
sbit O_DIR = IOA ^ 1;//PA.1电机方向
sbit O_ENABLE = IOA ^ 2;//PA.2电机使能(高->允许,低->禁止)
sbit O_SWITCH = IOA ^ 3;//PA.3电子开关(高->关闭,低->打开)
//////////////////////////////////////define variable
static WORD HighAddr;//高位地址
BYTE R_SPEED;//延时的机器周期数
BYTE R_STEP1;//电机行进步数高8位
BYTE R_STEP2;//电机行进步数250对应5um
BYTE R_STEP3;//电机行进步数200对应200*5um=1mm
BYTE R_LENGTH;//光栅长度,为光栅周期倍数
BYTE R_TIME1;//曝光时间高8位
BYTE R_TIME2;//曝光时间低8位
BYTE R_COEF;//写BRAG光栅时的倍数
BYTE R_SETTING;//命令
BOOL S_SWITCH;//电子开关设定
////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void TD_Init( void )
{ // Called once at startup
CPUCS = 0x02; // CLKSPD[1:0]=10, for 48MHz operation///10
// CPUCS = 0x12; // CLKOE=0, don't drive CLKOUT
GpifInit( ); // init GPIF engine via GPIFTool output file
SYNCDELAY; // see TRM section 15.14
REVCTL = 0x02; // REVCTL.1=1; use "dynamic OUT automaticity"
// EP2 512 BULK OUT 4x
SYNCDELAY; // see TRM section 15.14
EP2CFG = 0xA0; // BUF[1:0]=00 for 4x buffering
// EP6 512 BULK IN 4x
SYNCDELAY; //
EP6CFG = 0xE0; // BUF[1:0]=00 for 4x buffering
// EP4 and EP8 are not used in this implementation...
SYNCDELAY; //
EP4CFG = 0x20; // clear valid bit
SYNCDELAY; //
EP8CFG = 0x60; // clear valid bit
SYNCDELAY; //
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; //
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x04; // reset, FIFO 4
SYNCDELAY; //
FIFORESET = 0x06; // reset, FIFO 6
SYNCDELAY; //
FIFORESET = 0x08; // reset, FIFO 8
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL
// 8-bit bus (WORDWIDE=0)...
SYNCDELAY; //
EP2FIFOCFG = 0x00;
SYNCDELAY; //
EP6FIFOCFG = 0x04;
SYNCDELAY; //
EP2BCL = 0x80; // arm first buffer
SYNCDELAY; //
EP2BCL = 0x80; // arm second buffer
SYNCDELAY; //
EP2BCL = 0x80; // arm third buffer
SYNCDELAY; //
EP2BCL = 0x80; // arm fourth buffer
SYNCDELAY; //
// Note: had we choosen to use AUTOOUT=1 initially, then...
// (1)...when REVCTL.1=0, the core must see MANUAL-AUTO switch of AUTO bit
// ...to properly "arm" OUT buffers...
//
// SYNCDELAY;
// EP2FIFOCFG = 0x00; // AUTOOUT=0 (manual OUT mode)
// SYNCDELAY;
// EP6FIFOCFG = 0x04;
// then,
// SYNCDELAY;
// EP2FIFOCFG = 0x10; // AUTOOUT=1 (auto OUT mode)
// SYNCDELAY;
// EP6FIFOCFG = 0x04;
//
// ...this might not be obvious because the default is AUTOOUT=0
// ...power static back to back firmware downloads may be subject to
// ...the above scheme.when the application's last status was AUTOOUT=1
//
// (2)...when REVCTL.1=1, core blocks auto arming of OUT endp's
// ...see above EPxBCL/OUTPKTEND sequence(s)
// ...sequence is as follows:
// ...(a) REVCTL.1=1
// ...(b) FIFORESET (as above)
// ...(c) EPxBCL/OUTPKTEND (as above)
// ...(d) AUTOOUT=1
// IN endp's come up in the cpu/peripheral domain
// setup INT4 as internal source for GPIF interrupts
// using INT4CLR (SFR), automatically enabled
INTSETUP |= 0x03; // Enable INT4 FIFO/GPIF Autovectoring
SYNCDELAY; // used here as "delay"
EXIF &= ~0x40; // just in case one was pending...
SYNCDELAY; // used here as "delay"
GPIFIRQ = 0x02;
SYNCDELAY; //
GPIFIE = 0x02; // Enable GPIFWF interrupt
SYNCDELAY; //
EIE |= 0x04; // Enable INT4 ISR, EIE.2(EIEX4=1)
SYNCDELAY;
GPIFIDLECTL=0xFc;
SYNCDELAY;
}
#define GPIFTRIGWR 0
#define GPIFTRIGRD 4
#define GPIF_EP2 0
#define GPIF_EP4 1
#define GPIF_EP6 2
#define GPIF_EP8 3
void TD_Poll( void )
{ // Called repeatedly while the device is idle
static WORD xFIFOTC_OUT = 0x0000;
if(xfrvia_TD_Poll ) // Set to TRUE vendor command 0xD1...
{
if( !( EP2468STAT & 0x01 ) ) // Is the host busy sending data
{ // ...EP2E=0, when endp FIFO not ...empty, host sent pkt.
// Since the host sent data, a slave FIFO buffer was available
// ... GO on with GPIF write
if( GPIFTRIG & 0x80 ) // if GPIF done then check slave status
{
xFIFOTC_OUT = ((EP2BCH<<8) + EP2BCL);
if( xFIFOTC_OUT ) // pkt is not zerolen, xfr the data
{
EP2GPIFTCH = EP2BCH; // Setup transaction count
EP2GPIFTCL = EP2BCL; // Set EP2GPIFTC = EP2BC
EP2BCL = 0x00; // AUTOOUT=0, so "pass-on" pkt. to master (GPIF)
// Skip bit is 0 +> pass on packet to master
// Once master xfr's OUT pkt, it "auto" (re)arms
GPIFTRIG = GPIF_EP2; // Trigger FIFO write transaction(s), using SFR
// R/W=0, EP[1:0]=FIFO_EpNum for EPx write(s)
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
}
//////////////////////////////////////////////////////////////更新高位的地址线/////////
if(LSB(xFIFOTC_OUT))//如果传输了64字节
{
HighAddr+=1;
}
else
{
HighAddr+=8;
}
IOD=LSB(HighAddr>>3);
IOE=MSB(HighAddr>>3);
///////////////////////////////////////////////////////////////////////////////////////
}
else // Handle host sending zero length pkt.
{
EP2BCL = 0x80; // AUTOOUT=0, so "skip" zerolen pkt and manually commit packet to the master
}
}
else
{ // GPIF is busy
}
}
else // Host is "not" sending data and the
{ // ...slave has taken all data and
} // ...nothing in the buffer
// Does the slave have data for us...
if( GPIFTRIG & 0x80 ) // If GPIF done then check slave status
{
if( in_token_event ) // Set via vendor command 0xE0
{
if( !( EP2468STAT & 0x20 ) )// if EP6F=0, buffer is available
{
// Trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
EP6GPIFTCH = 0x00; // setup transaction count
EP6GPIFTCL = 0x40; // set EP8GPIFTC = 8
if( !( EP2468STAT & 0x20 ) )
{ // EP8FF=0, when buffer is available...
// trigger FIFO read transaction(s), using SFR
while( !( GPIFTRIG & 0x80 ) ) // Poll GPIFTRIG.7 Done bit
{
}
GPIFTRIG = GPIFTRIGRD | GPIF_EP6; // R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
*EP0BUF = 0xA8; // return that there was a buffer available
}
else
{ // If EP busy then host is behind...two buffers containing data
}
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
}
INPKTEND = 0x06; // AUTOIN=0, so 8051 must "pass-on" pkt to host
HighAddr+=1;
IOD=LSB(HighAddr>>3);
IOE=MSB(HighAddr>>3);
} // ....to the INPKTEND register
else // If EP busy then host is behind (slow) and we
{ // ...still have two buffers containing data
}
}
else // in_token_event not asserted by vendor request
{
}
}
else // GPIF is busy
{
}
}
else
{
}
}
BOOL TD_Suspend( void )
{ // Called before the device goes into suspend mode
return( TRUE );
}
BOOL TD_Resume( void )
{ // Called after the device resumes
return( TRUE );
}
//-----------------------------------------------------------------------------
// Device Request hooks
// The following hooks are called by the end point 0 device request parser.
//-----------------------------------------------------------------------------
BOOL DR_GetDescriptor( void )
{
return( TRUE );
}
BOOL DR_SetConfiguration( void )
{ // Called when a Set Configuration command is received
if( EZUSB_HIGHSPEED( ) )
{ // ...FX2 in high speed mode
SYNCDELAY; //
EP6AUTOINLENH = 0x02; // set core AUTO commit len = 512 bytes
SYNCDELAY; //
EP6AUTOINLENL = 0x00;
SYNCDELAY; //
enum_pkt_size = 512; // max. pkt. size = 512 bytes
}
else
{ // ...FX2 in full speed mode
SYNCDELAY; //
EP6AUTOINLENH = 0x00; // set core AUTO commit len = 64 bytes
SYNCDELAY; //
EP6AUTOINLENL = 0x40;
SYNCDELAY; //
enum_pkt_size = 64; // max. pkt. size = 64 bytes
}
Configuration = SETUPDAT[ 2 ];
return( TRUE ); // Handled by user code
}
BOOL DR_GetConfiguration( void )
{ // Called when a Get Configuration command is received
EP0BUF[ 0 ] = Configuration;
EP0BCH = 0;
EP0BCL = 1;
return(TRUE); // Handled by user code
}
BOOL DR_SetInterface( void )
{ // Called when a Set Interface command is received
AlternateSetting = SETUPDAT[ 2 ];
return( TRUE ); // Handled by user code
}
BOOL DR_GetInterface( void )
{ // Called when a Set Interface command is received
EP0BUF[ 0 ] = AlternateSetting;
EP0BCH = 0;
EP0BCL = 1;
return( TRUE ); // Handled by user code
}
BOOL DR_GetStatus( void )
{
return( TRUE );
}
BOOL DR_ClearFeature( void )
{
return( TRUE );
}
BOOL DR_SetFeature( void )
{
return( TRUE );
}
///////////////////////////////////////////////////////////子函数/////////////
void SUB_SETTING(void)
{
if(R_SETTING&0x01)//设置O_DIR
IOA|=0x02;
else
IOA&=0xFD;
if(R_SETTING&0x02)//设置S_SWITCH
S_SWITCH=1;
else
S_SWITCH=0;
}
void SUB_STEPIN(void)
{
BYTE i,j,k,l;
if(S_SWITCH)//根据电子开关设定决定是否打开电子开关
IOA&=0xF7;//clear O_SWITCH
for(i=R_STEP1;i>0;i--)
for(j=R_STEP3;j>0;j--)
for(k=R_STEP2;k>0;k--)
{
IOA^=0x01;//CPL IOA.0(O_STEP)
for(l=R_SPEED;l>0;l--);
IOA^=0x01;//CPL IOA.0(O_STEP)
for(l=R_SPEED;l>0;l--);
}
IOA|=0x08;//SETB O_SWITCH
}
void SUB_F1(void)
{
BYTE i,j,k,l;
for(i=R_LENGTH;i>0;i--)
{
IOA&=0xF7;//CLR O_SWITCH
for(j=R_TIME1;j>0;j--)
{
for(l=100;l>0;l--)
{
for(k=R_TIME2;k>0;k--);
for(k=R_TIME2;k>0;k--);
}
}
if(!S_SWITCH)//根据S_SWITCH标志决定是否关闭电子开关
{
IOA|=0x08;//SETB O_SWITCH
}
for(j=R_STEP1;j>0;j--)
{
for(k=R_STEP2;k>0;k--)
{
IOA^=0x01;//CPL O_STEP(IOA.0)
for(l=R_SPEED;l>0;l--);
IOA^=0x01;//CPL O_STEP(IOA.0)
for(l=R_SPEED;l>0;l--);
//没有STOP中断
}
}
}
IOA|=0x08;//SETB O_SWITCH
}
//////////////////////////////////////////////////////////////////////////////
BOOL DR_VendorCmnd( void )
{
switch( SETUPDAT[ 1 ] )
{
case VX_A2:
{ // Get status of peripheral function, by doing a GPIF single read transaction
// using register(s) in XDATA space, dummy read
SYNCDELAY;
GPIFIDLECTL=0xFD;
SYNCDELAY;
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
}
*EP0BUF = XGPIFSGLDATLX; // trigger GPIF single byte read transaction
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
}
// EP0BUF[0]=XGPIFSGLDATH;
EP0BUF[0] = XGPIFSGLDATLNOX; // ...GPIF reads byte from PERIPHERAL
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
return( FALSE );
break;
}
case VX_A3:
{ // Tell peripheral we're going into HS mode, by doing a GPIF single write transaction
while( !( GPIFTRIG & 0x80 ) ) // Poll GPIFTRIG.7 Done bit
{
}
XGPIFSGLDATLX = 0xA3; // Trigger GPIF
*EP0BUF = 0xA3;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_A7:
{ // Setup peripheral for high speed FIFO xfr(s), TC=8 bytes
EP6GPIFTCH = 0x00; // setup transaction count
EP6GPIFTCL = 0x40; // set EP8GPIFTC = 8
*EP0BUF = 0xA7;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_A8:
{ // Do a FIFO Rd transaction w/TC=8 into EP8
if( !( EP2468STAT & 0x20 ) )
{ // EP8FF=0, when buffer is available...
// trigger FIFO read transaction(s), using SFR
while( !( GPIFTRIG & 0x80 ) ) // Poll GPIFTRIG.7 Done bit
{
}
GPIFTRIG = GPIFTRIGRD | GPIF_EP6; // R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
*EP0BUF = 0xA8; // return that there was a buffer available
}
else
{ // If EP busy then host is behind...
*EP0BUF = 0x00; // Buffer space wasn't available and we still have
// two buffers containing data
}
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_AC:
{ // manually commit IN data to host...
// GPIF needs to still be pointing to EP8, last FIFO accessed
if( EP2468STAT & 0x20 )
{ // EP6F=1 when buffer is not available
*EP0BUF = 0x00; // buffer wasn't available
}
else
{ // EP8F=0 when buffer is available
INPKTEND = 0x06; // 8051 commits pkt by writing #8 to INPKTEND
*EP0BUF = 0xAC;
}
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_C5:
{ // read REVCTL register
HighAddr=0xAAAA;
EP0BUF[0]=LSB(HighAddr>>3);
EP0BUF[1]=MSB(HighAddr>>3);
EP0BCH = 0;
EP0BCL = 2; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK;
return( FALSE );
break;
}
case VX_D0:
{ // read live GPIF address
EP0BUF[0] = VX_D0;
SYNCDELAY;
EP0BUF[3]=GPIFADRH;
SYNCDELAY;
EP0BUF[4]=GPIFADRL;
EP0BUF[2]=IOD;
EP0BUF[1]=IOE;
EP0BCH = 0;
EP0BCL = 5; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
return( FALSE ); // no error; command handled OK
break;
}
case VX_D1:
{ // setup GPIF transaction count
xfrvia_TD_Poll = 1;
in_token_event=0;
//ledX_rdvar = LED0_ON; // LED0 is ON: GPIF triggered in TD_POll
*EP0BUF = 0xD1;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_D2:
{
xfrvia_TD_Poll = 0;
in_token_event=1;
//ledX_rdvar = LED0_OFF; // LED0 is OFF: GPIF not triggered in TD_Poll
*EP0BUF = 0xD2;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
case VX_E0://握手
{
*EP0BUF=VX_E0;
break;
}
case VX_E1://电子开关 EP0BUF[1]=0x00关闭,EP0BUF【1】=0x01打开
{
if(EP0BUF[1]&0x01)
IOA &=0xF7;//IOA.3=0
else
IOA |=0x08;//IOA.3=1
*EP0BUF=VX_E1;
break;
}
case VX_E2:
//电机行进,四个字节命令,EP0BUF【0】为原始命令,EP0BUF【1】存储设置信息,
//EP0BUF【2】控制电机速度(延时参数),EP0BUF【3】为行进步数
//EP0BUF【1】.0设置方向O_DIR,EP0BUF【1】。1设置电子开关O_SWITCH,SWITCH=0关闭,SWITCH=1打开
{
R_SETTING=EP0BUF[1];
R_SPEED=EP0BUF[2];
R_STEP1=EP0BUF[3];
R_STEP2=0xFA;//=250
R_STEP3=0xC8;//=200
SUB_SETTING();
SUB_STEPIN();
*EP0BUF=VX_E2;
break;
}
case VX_E3://长周期光栅的制作
{
R_SETTING=EP0BUF[1];
R_SPEED=EP0BUF[2];
R_STEP1=EP0BUF[3];
R_STEP2=0xFA;//250
R_LENGTH=EP0BUF[4];
R_TIME1=EP0BUF[5];
R_TIME2=EP0BUF[6];
SUB_SETTING();
SUB_F1();
*EP0BUF=VX_E3;
break;
}
/* case VX_E4:
{
if( EP68FIFOFLGS & 0x01 )
{ // EP6FF=1, when fifo "full"
SYNCDELAY; //
INPKTEND = 0x06; // ...skip pkt.
}
else
{ // EP6FF=0, when fifo "not full", buffer available...
// setup GPIF transaction count
SYNCDELAY; //
EP6GPIFTCH = 0x02;
SYNCDELAY;
EP6GPIFTCL = 0x00;
// trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
SYNCDELAY;
GPIFTRIG = GPIFTRIGRD | GPIF_EP6;
// NOTE: 512 bytes transfers in ~75usec on 8-bit async bus ;64 bytes transfers in ~10usec on 8-bit async bus
// wait for the transaction to terminate naturally...
SYNCDELAY; //
while( !( GPIFTRIG & 0x80 ) )
{ // should take <75usec @ 8-bit async.
; // poll GPIFTRIG.7, DONE bit...
}
}
*EP0BUF=VX_E4;
break;
//电子开关,按存储器数据运行
{
if(EP0BUF[1]&0x02)
{
IOA&=0xF7;//CLR O_SWTICH
}
else
{
}
IOA&=0xFD;//CLR O_DIR
R_COEF=EP0BUF[2];
ReadFlag=1;
IOD=0x00;
IOE=0x00;
AUTOPTRSETUP = 0x07;
while(ReadFlag)
{
AUTOPTRH2 = 0xF8;
AUTOPTRL2 = 0x00;//EP6BUFFER
//if ep6full is full then do work;close switch;skip packet;ep6full=0;ReadFlag=1;
// Handle IN data...
// is the peripheral interface idle...
if( GPIFTRIG & 0x80 )
{ // check if peripheral "not empty"...
if( EP68FIFOFLGS & 0x01 )
{ // EP6FF=1, when fifo "full"
BYTE i,j,k,l,delay;
for(l=2;l>0;l--)
{
for(i=256;i>0;i--)
{
IOA^=0x01;
delay=EXTAUTODAT2;
if(!delay)
{
ReadFlag=0;
IOA|=0x08;
i=0;
j=0;
}
IOA^=0x01;
for(j=R_COEF;j>0;j--)//延时
{
for(k=delay;k>0;k--);
}
}
}
IOD+=1;
if(PSW&0x80)
{
IOE+=1;
}
SYNCDELAY; //
INPKTEND = 0x16; // ...skip pkt.
}
else
{ // EP6FF=0, when fifo "not full", buffer available...
// setup GPIF transaction count
SYNCDELAY; //
EP6GPIFTCH = 0x02;
SYNCDELAY;
EP6GPIFTCL = 0x00;
// trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
SYNCDELAY;
GPIFTRIG = GPIFTRIGRD | GPIF_EP6;
// NOTE: 512 bytes transfers in ~75usec on 8-bit async bus ;64 bytes transfers in ~10usec on 8-bit async bus
// wait for the transaction to terminate naturally...
SYNCDELAY; //
while( !( GPIFTRIG & 0x80 ) )
{ // should take <75usec @ 8-bit async.
; // poll GPIFTRIG.7, DONE bit...
}
}
}
else
{ // peripheral interface busy...
}
}
IOA|=0x08;
*EP0BUF=VX_E4;
break;
}
*/ case VX_E5:
//数据传输的初始化工作
{
IOD=0x00;
IOE=0x00;
*EP0BUF=VX_E5;
break;
}
case VX_EE:
{
// GPIF address pins update when GPIFADRH/L written
SYNCDELAY; //
GPIFADRH = 0x00; // bits[7:1] always 0
SYNCDELAY; //
GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
IOD=0x00;
IOE=0x00;
HighAddr=0x0000;
*EP0BUF = 0xEE;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
}
////////////////////////////////////////////////////////////////////////////////////////////
default:
{
//ledX_rdvar = LED3_ON; // debug visual, stuck "ON" to warn developer...
return( FALSE ); // no error; command handled OK
}
}
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
return( FALSE ); // no error; command handled OK
}
//-----------------------------------------------------------------------------
// USB Interrupt Handlers
// The following functions are called by the USB interrupt jump table.
//-----------------------------------------------------------------------------
// Setup Data Available Interrupt Handler
void ISR_Sudav( void ) interrupt 0
{
GotSUD = TRUE; // Set flag
EZUSB_IRQ_CLEAR( );
USBIRQ = bmSUDAV; // Clear SUDAV IRQ
}
// Setup Token Interrupt Handler
void ISR_Sutok( void ) interrupt 0
{
EZUSB_IRQ_CLEAR( );
USBIRQ = bmSUTOK; // Clear SUTOK IRQ
}
void ISR_Sof( void ) interrupt 0
{
EZUSB_IRQ_CLEAR( );
USBIRQ = bmSOF; // Clear SOF IRQ
}
void ISR_Ures( void ) interrupt 0
{
if ( EZUSB_HIGHSPEED( ) )
{
pConfigDscr = pHighSpeedConfigDscr;
pOtherConfigDscr = pFullSpeedConfigDscr;
}
else
{
pConfigDscr = pFullSpeedConfigDscr;
pOtherConfigDscr = pHighSpeedConfigDscr;
}
EZUSB_IRQ_CLEAR( );
USBIRQ = bmURES; // Clear URES IRQ
}
void ISR_Susp( void ) interrupt 0
{
Sleep = TRUE;
EZUSB_IRQ_CLEAR( );
USBIRQ = bmSUSP;
}
void ISR_Highspeed( void ) interrupt 0
{
if ( EZUSB_HIGHSPEED( ) )
{
pConfigDscr = pHighSpeedConfigDscr;
pOtherConfigDscr = pFullSpeedConfigDscr;
}
else
{
pConfigDscr = pFullSpeedConfigDscr;
pOtherConfigDscr = pHighSpeedConfigDscr;
}
EZUSB_IRQ_CLEAR( );
USBIRQ = bmHSGRANT;
}
void ISR_Ep0ack( void ) interrupt 0
{
}
void ISR_Stub( void ) interrupt 0
{
}
void ISR_Ep0in( void ) interrupt 0
{
}
void ISR_Ep0out( void ) interrupt 0
{
}
void ISR_Ep1in( void ) interrupt 0
{
}
void ISR_Ep1out( void ) interrupt 0
{
}
void ISR_Ep2inout( void ) interrupt 0
{
}
void ISR_Ep4inout( void ) interrupt 0
{
}
void ISR_Ep6inout( void ) interrupt 0
{
}
void ISR_Ep8inout( void ) interrupt 0
{
}
void ISR_Ibn( void ) interrupt 0
{
}
void ISR_Ep0pingnak( void ) interrupt 0
{
}
void ISR_Ep1pingnak( void ) interrupt 0
{
}
void ISR_Ep2pingnak( void ) interrupt 0
{
}
void ISR_Ep4pingnak( void ) interrupt 0
{
}
void ISR_Ep6pingnak( void ) interrupt 0
{
}
void ISR_Ep8pingnak( void ) interrupt 0
{
}
void ISR_Errorlimit( void ) interrupt 0
{
}
void ISR_Ep2piderror( void ) interrupt 0
{
}
void ISR_Ep4piderror( void ) interrupt 0
{
}
void ISR_Ep6piderror( void ) interrupt 0
{
}
void ISR_Ep8piderror( void ) interrupt 0
{
}
void ISR_Ep2pflag( void ) interrupt 0
{
}
void ISR_Ep4pflag( void ) interrupt 0
{
}
void ISR_Ep6pflag( void ) interrupt 0
{
}
void ISR_Ep8pflag( void ) interrupt 0
{
}
void ISR_Ep2eflag( void ) interrupt 0
{
}
void ISR_Ep4eflag( void ) interrupt 0
{
}
void ISR_Ep6eflag( void ) interrupt 0
{
}
void ISR_Ep8eflag( void ) interrupt 0
{
}
void ISR_Ep2fflag( void ) interrupt 0
{
}
void ISR_Ep4fflag( void ) interrupt 0
{
}
void ISR_Ep6fflag( void ) interrupt 0
{
}
void ISR_Ep8fflag( void ) interrupt 0
{
}
void ISR_GpifComplete( void ) interrupt 0
{
}
void ISR_GpifWaveform( void ) interrupt 0
{ // FIFORd WF detected peripheral prematurely empty (less than max. pkt. size)
GPIFABORT = 0xFF; // abort to handle shortpkt
SYNCDELAY;
EXIF &= ~0x40;
INT4CLR = 0xFF; // automatically enabled at POR
SYNCDELAY;
}