📄 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -