📄 gpifburst8a.c
字号:
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: gpifburst8a.c v0.3 - (implemented for rev B silicon only)
// Contents: Hooks required to implement USB peripheral function.
//
// Copyright (c) 1997 AnchorChips, Inc. 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
// EZUSB FX2 PORTA i/o...
sbit SHORTPKT = IOA ^ 0;
sbit PA1 = IOA ^ 1;
sbit PA2 = IOA ^ 2;
sbit PA3 = IOA ^ 3;
sbit PA4 = IOA ^ 4;
sbit PA5 = IOA ^ 5;
sbit PA6 = IOA ^ 6;
sbit PA7 = IOA ^ 7;
// EZUSB FX2 PORTD = FD[15:8], when IFCFG[1:0]=10 and WORDWIDE=1
sbit PD0 = IOD ^ 0;
sbit PD1 = IOD ^ 1;
sbit PD2 = IOD ^ 2;
sbit PD3 = IOD ^ 3;
sbit PD4 = IOD ^ 4;
sbit PD5 = IOD ^ 5;
sbit PD6 = IOD ^ 6;
sbit PD7 = IOD ^ 7;
// EZUSB FX2 PORTE is not bit-addressable...
// PORTE.7 - GPIFADR[8], when IFCFG[1:0]=10 and PORTECFG.7=1
// Debug LEDs: accessed via movx reads only ( through CPLD )
xdata volatile const BYTE LED0_ON _at_ 0x8000; // GPIF event triggered in TD_Poll
xdata volatile const BYTE LED0_OFF _at_ 0x8100; // GPIF Event triggered by vendor request
xdata volatile const BYTE LED1_ON _at_ 0x9000; // Vendor request is copmpleted succesfully
xdata volatile const BYTE LED1_OFF _at_ 0x9100;
xdata volatile const BYTE LED2_ON _at_ 0xA000; // Empty buffer
xdata volatile const BYTE LED2_OFF _at_ 0xA100;
xdata volatile const BYTE LED3_ON _at_ 0xB000;
xdata volatile const BYTE LED3_OFF _at_ 0xB100;
// NOTE: The default monitor loads at 0xC000
BYTE ledX_rdvar = 0x00; // Use this global variable when (de)asserting debug LEDs
BOOL xfrvia_TD_Poll = 0; // Event flg for execution in TD_Poll( );
BOOL in_token_event = 0; // Event flg for GPIF FIFO Read trigger
// Core uses bRequest value 0xA0 for Anchor downloads/uploads...
// Cypress Semiconductor reserves bRequest values 0xA1 through 0xAF...
// Your implementation should not use the above bRequest values...
// Also, previous fw.c versions trap all bRequest values 0x00 through 0x0F...
//
// bRequest value: SETUPDAT[1]
// standard, 0x00 through 0x0F
//
// bmRequest value: SETUPDAT[0]
// standard, 0x80 IN Token
// vendor, 0xC0 IN Token
// class, 0xA0 IN Token
// standard, 0x00 OUT Token
// vendor, 0x40 OUT Token
// class, 0x60 OUT Token
#define VX_A2 0xA2 // testing, GPIF single byte read waveform
#define VX_A3 0xA3 // testing, GPIF single byte write waveform
#define VX_A4 0xA4 // testing, GPIFABORT
#define VX_A6 0xA6 // turn debug LED[3:0] off...
#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_A9 0xA9 // do a FIFO Wr transaction w/TC=BC from EP2
#define VX_AA 0xAA // manually commit IN data to host... EP8BC=FIFOBC
#define VX_AB 0xAB // manually commit OUT data to master...
#define VX_AC 0xAC // manually commit IN data to host... INPKTEND
#define VX_AD 0xAD // setup GPIF FIFO Reads w/TC=8
#define VX_AE 0xAE // return status of GPIF
#define VX_AF 0xAF // comitt one zerolen IN pkts
#define VX_B1 0xB1 // examine flag status, XDATA - EP8FIFOFLGS
#define VX_B2 0xB2 // examine flag status, XDATA - EP8CS
#define VX_B3 0xB3 // examine flag status, SFR - EP68FIFOFLGS
#define VX_B4 0xB4 // examine ep8bch
#define VX_B5 0xB5 // examine ep8bcl
#define VX_B6 0xB6 // examine ep8fifobcl
#define VX_B7 0xB7 // examine ep8fifobcl
#define VX_C1 0xC1 // examine flag status, XDATA - EP2FIFOFLGS
#define VX_C2 0xC2 // examine flag status, XDATA - EP2CS
#define VX_C3 0xC3 // examine flag status, SFR - EP24FIFOFLGS
#define VX_C4 0xC4 // examine ep2bch
#define VX_C5 0xC5 // examine ep2bcl
#define VX_C6 0xC6 // examine ep2fifobcl
#define VX_C7 0xC7 // examine ep2fifobcl
#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_E0 0xE0 // set GPIF FIFO Read event flag
// Protocols from gpif.c
void GpifInit( void );
// Some #defines from gpif.c, typically be in a common header file
#define GPIF_FLGSELPF 0
#define GPIF_FLGSELEF 1
#define GPIF_FLGSELFF 2
#define GPIFTRIGWR 0
#define GPIFTRIGRD 4
#define GPIF_EP2 0
#define GPIF_EP4 1
#define GPIF_EP6 2
#define GPIF_EP8 3
//#define USING_REVD // Select silicon revision (comment for REVB)
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void BLINK_LED(void)
{
ledX_rdvar = LED2_ON; // LED1 is ON => vend request completed
EZUSB_Delay(1000); // Wait for 1 second
ledX_rdvar = LED2_OFF; // LED1 is off => reset LED1
}
void TD_Init( void )
{ // Called once at startup
#ifdef USING_REVD
// 8051 sets CLKSPD...
CPUCS = 0x10; // CLKSPD[1:0]=10, for 48MHz operation
// ...default 12MHz...
// don't drive CLKOUT (CLKOE=0=>Not Driving CLKOUT)
#else
// FX2 REVB silicon...
// CLKSPD[1:0] core sets via serial eeprom config byte values
// ...default 48MHz...
// CLKOE bit has swapped bit setting...
CPUCS = 0x02; // don't drive CLKOUT (CLKOE=1=>Not Driving CLKOUT)
#endif
GpifInit( ); // Configure GPIF from GPIFTool generated waveform data
#ifdef USING_REVD
SYNCDELAY;
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; // see TRM section 15.14
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x08; // reset, FIFO 8
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL
#else
SYNCDELAY;
FIFORESET = 0xFF; // reset ALL slave fifo's (2,4,6,8)
#endif
// default: all endpoints have their VALID bit set
// default: TYPE1 = 1 and TYPE0 = 0 --> BULK
// default: EP2 and EP4 DIR bits are 0 (OUT direction)
// default: EP6 and EP8 DIR bits are 1 (IN direction)
// default: EP2, EP4, EP6, and EP8 are double buffered
SYNCDELAY;
EP2FIFOCFG = 0x04;
// NA=0 , NULL bit field
// INFM1=0 , don't IN full minus 1 status flag
// OEP1=0 , don't OUT empty plus 1 status flag, not used for IN endp
// AUTOOUT=0 , use manual mode, 8051 is responsible for commit pkt(s).
// AUTOIN=0 , not applicable for OUT endp
// ZEROLENIN=1 , send zerolen pkt on PKTEND
// NA=0 , NULL bit field
// WORDWIDE=0 , use 8-bit databus
// The EPx WORDWIDE bits must to be set to configure
// ...PORTD as FD[15:8] for single transactions if "any"
// ...of the WORDWIDE bits are set, then PORTD is FD[15:8]
SYNCDELAY;
EP8FIFOCFG = 0x04;
// Since we're in manual mode, we need to initially arm out pkt(s)
// Out endpoints do not come up armed. Need to be armed
// Since the defaults are double buffered we must write
// ...dummy byte counts twice
SYNCDELAY;
EP2BCL = 0x80; // Commit buffer, 1x - w/skip=1
SYNCDELAY;
EP2BCL = 0x80; // Commit buffer, 2x - w/skip=1
EP8AUTOINLENH = 0x02; // When AUTOIN=1, core commits IN data
EP8AUTOINLENL = 0x00; // ...when EPxAUTOINLEN value is met
PORTACFG = 0x00; // PORTA as I/O pins
OEA = 0xFF; // Set PORTA as outputs
GPIFADRH = 0x00; // Setup initial gpif address
GPIFADRL = 0x00; // ...outputs.
EP8GPIFTCH = 0x00; // Setup initial transaction count
EP8GPIFTCL = 0x08; // EP8GPIFTC = 8 bytes
// Turn debug LED[3:0] off (default)
ledX_rdvar = LED0_OFF;
ledX_rdvar = LED1_OFF;
ledX_rdvar = LED2_OFF;
ledX_rdvar = LED3_OFF;
}
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...
{
ledX_rdvar = LED0_ON; // LED0 is ON: GPIF triggered in TD_POll
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
{
ledX_rdvar = LED1_OFF; // GPIF is not busy
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)
if(xFIFOTC_OUT < 0x0200)// Handle short pkt. to slave, via PA0
{
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
ledX_rdvar = LED1_ON; // GPIF busy
}
SHORTPKT = 0; // Signal SHORTPKT to slave (PA0)
SHORTPKT = 1;
}
else // Was max pkt. size
{
}
}
else // Handle host sending zero length pkt.
{
EP2BCL = 0x80; // AUTOOUT=0, so "skip" zerolen pkt.
// Manually commit packet to the master
SHORTPKT = 0; // Signal SHORTPKT to slave (PA0)
SHORTPKT = 1;
}
}
else // GPIF is busy
{
ledX_rdvar = LED1_ON; // GPIF is still busy withthe last transfer
}
}
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
{
ledX_rdvar = LED1_OFF; // GPIF is not busy
if( in_token_event ) // Set via vendor command 0xE0
{
ledX_rdvar = LED0_OFF;
if( !( EP2468STAT & 0x80 ) )// if EP8F=0, buffer is available
{
// Trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
GPIFTRIG = GPIFTRIGRD | GPIF_EP8;
in_token_event = 0;// Clear event flag
while( !( GPIFTRIG & 0x80 ) ) // poll GPIFTRIG.7 Done bit
{
ledX_rdvar = LED1_ON; // GPIF busy
}
INPKTEND = 0x08; // AUTOIN=0, so 8051 must "pass-on" pkt to host
// Short packet => commit to hoist by writting endp
} // ....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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -