:beer;The following is the source code:
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: FX2_to_extsyncFIFO.c
// Contents: Hooks required to implement FX2 GPIF to external sync. FIFO
// interface using CY4265-15AC
//
// Copyright (c) 2003 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "fx2sdly.h" // SYNCDELAY macro, see Section 15.14 of FX2 Tech.
// Ref. Manual for usage details.
#define EXTFIFONOTFULL GPIFREADYSTAT & bmBIT1
#define EXTFIFONOTEMPTY GPIFREADYSTAT & bmBIT0
extern BOOL GotSUD; //Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;
BYTE Configuration; //Current configuration
BYTE AlternateSetting; //Alternate settings
extern BOOL in_enable; //Flag enable IN transfers
BOOL enum_high_speed = FALSE; //Flag to let firmware know FX2 enumerated at high speed
extern const char xdata FlowStates[36];
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void Setup_FLOWSTATE_Read ( void );
//void GpifInit ();
void TD_Init(void) //Called once at startup
{
//Set the CPU clock to 48MHz
CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1);
//FIFO interface
//**********************************************//
SYNCDELAY;
IFCONFIG=0x13;//IFCONFIG.7 selects between internal and external sources: 0 = external, 1 = internal.
//IFCONFIG.6 selects between the 30- and 48-MHz internal clock: 0 = 30 MHz, 1 = 48 MHz.
//IFCONFIG.5 is the output enable for the internal clock source: 0 = disable, 1 = enable.
//IFCONFIG.4 inverts the polarity of the interface clock (whether it's internal or external): 0 = normal,1 = inverted.
//IFCONFIG.3 = 1 asynchronous mode; IFCONFIG.3 = 0 synchronous mode
//IFCFG1 IFCFG0
// 0 0 Ports
// 0 1 Reserved
// 1 0 GPIF Interface (internal master)
// 1 1 Slave FIFO Interface (external master)
//REVCTL
//**********************************************//
SYNCDELAY;
REVCTL=0x01; //SET REVCTL.0=0 & REVCTL.1=1
//USB Domain of the FIFO
//***********************************************************//
SYNCDELAY; //EP1OUTCFG, EP1INCFG
EP1OUTCFG=0xA0; // Bit7 bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
SYNCDELAY; // VALID 0 TYPE1 TYPE0 0 0 0 0
EP1INCFG=0xA0; //TYPE[1:0], 00,01=VALID; 10=BULK; 11=INTERRUPT;
SYNCDELAY; //EPxCFG where x=2,4,6,8
EP2CFG = 0xE8; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
SYNCDELAY; // VALID DIR TYPE1 TYPE0 SIZE 0 BUF1 BUF0
EP4CFG = 0x00; //DIR:0=OUT; 1=IN.
SYNCDELAY; //TYPE[1:0], 00=Invalid, 01=ISOCHRONOUS, 10=BULK, 11=INTERRUPT
EP6CFG = 0x00; //SIZE: 0=512 bytes, 1=1024 bytes.
SYNCDELAY; //BUF[1:0], 00=Quad, 01=Invalid, 10=Double, 11=Triple.
EP8CFG = 0x00;
//Reset FIFOs
//***********************************************************//
SYNCDELAY;
FIFORESET = 0x80; //Write 0x80 to this register to NAK all transfers from the host, then write 0x02, 0x04, 0x06, or 0x08
SYNCDELAY; //to reset an individual FIFO (i.e., to restore endpoint FIFO flags and byte counts to their default
FIFORESET = 0x02; //states), then write 0x00 to restore normal operation.
SYNCDELAY;
FIFORESET = 0x00;
//Peripheral Domain side of FIFO
//**********************************************************//
SYNCDELAY;
EP2FIFOCFG = 0x09; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 0 INFM1 OEP1 AUTOOUT AUTOIN ZEROLENIN 0 WORDWIDE
//INFM1==1, The FIFO falgs for that endpoint become valid one sample earlier than when the FULL condition occurs. only to IN endpoints and operating synchronously.
//OEP1==1, The FIFO for that endpoint become valid one sample earlier than when the EMPTY condition occurs. applies only to OUT endpoints and operating aschrously.
//WORDWIDE applies when IFCFG=11 or 10.
//*******************************************************//
//FLAGA,FLAGB,FLAGC,FLAGD
SYNCDELAY;
PINFLAGSAB=0x00; //FLAGx3 FLAGx2 FLAGx1 FLAGx0 Pin Function
SYNCDELAY; // 0 0 0 0 FLAGA=PF, FLAGB=FF, FLAGC=EF, FLAGD=EP2PF.
PINFLAGSCD=0x40; // 0 0 0 1 Reserved
// 0 0 1 0 Reserved
// 0 0 1 1 Reserved
// 0 1 0 0 EP2 PF
// 0 1 0 1 EP4 PF
// 0 1 1 0 EP6 PF
// 0 1 1 1 EP8 PF
// 1 0 0 0 EP2 EF
// 1 0 0 1 EP4 EF
// 1 0 1 0 EP6 EF
// 1 0 1 1 EP8 EF
// 1 1 0 0 EP2 FF
// 1 1 0 1 EP4 FF
// 1 1 1 0 EP6 FF
// 1 1 1 1 EP8 FF
//*******************************************************//
SYNCDELAY;
FIFOPINPOLAR=0x3F; // Bit5 (PKTEND) 0:active low; 1:active high
// Bit4 (SLOE) 0:active low; 1:active high
// Bit3 (SLRD) 0:active low; 1:active high
// Bit2 (SLWR) 0:active low; 1:active high
// Bit1 (Empty Flag) 0:active low; 1:active high
// Bit0 (Full Flag) 0:active low; 1:active high
//*******************************************************//
SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
EP2FIFOPFH=0x81; // DECIS PKTSTAT IN:PKTS[2] IN:PKTS[1] IN:PKTS[0] 0 PFC9 PFC8
SYNCDELAY; // OUT:PFC12 OUT:PFC11 OUT:PFC10 0
EP2FIFOPFL=0x00; // For OUT packets, DECIS=0 (or 1):PF is asserted when the number is less/equal (or greater/equal) the threshold.
// For IN packets, PKTSTAT=1, The threshold is stored in PFC9:0, PKTSTAT=0, the threshold is stored in PKTS2:0 and PFC9:0
//*******************************************************//
SYNCDELAY;
PORTACFG=0x00; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
//FLAGD SLCS 0 0 0 0 INT1 INT0
//FLAGD=1 when IFCFG[1:0]=11 configures PA7 as FLAGD.
//SLCS=1 when IFCFG[1:0]=11 configures PA7 as S\L\C\S\.
//INT[1:0] configures PA[1:0] as INT1 and INT0 pins.
//*******************************************************//
SYNCDELAY;
OEA|=0x88; //Output Enable (Port A) PORTA.7: Enable PORTA.3:Enable
SYNCDELAY;
IOA=0x88; //PORTA.3=1 reset and suspend the FPGA.
//******************************************************//
SYNCDELAY;
IE|=0x80; // IE.7 IE.6 IE.5 IE.4 IE.3 IE.2 IE.1 IE.0
// EA Serial_1 Timer_2 Serial_0 Timer_1 External_1 Timer_0 External_0
//*************************EIE******************************//
SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
EIE|=0x05; // EX6 EX5 EX4 EI2C EUSB
//*****************Enable selected interrupts****************
USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 0 EP0ACK HSGRANT URES SUSP SUTOK SOF SUDAV
//**************************IP******************************//
IP=0x05; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 1 Serial_1 Timer_2 Serial_0 Timer_1 INT1 Timer_0 INT0
//=1:high priority, =0:low priority
//*************************EIP******************************//
EIP=0x01; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 1 1 1 INT6 INT5 INT4/GPIF/FIFO I2CINT PUSB
//=1: high priority, =0: low priority
//*************************Endpoint Interrupt Enable********//
SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
EPIE|=0x08; // EP8 EP6 EP4 EP2 EP1OUT EP1IN EP0OUT EPOIN
//****************EP2 Slave FIFO Flag Interrupt Enable******//
EP2FIFOIE=0x01; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 0 0 0 0 EDGEPF PF EF FF
//EDGE=0 (or 1), the interrupt fires on the rising (falling) edge of the programmable flag
//*************************TCON*****************************//
SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
TCON=0x05; // TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
//TCON.2(IT1) - INT1 is detected on falling edge when IT1 = 1; INT1 is detected as a low level when IT1 = 0.
//TCON.0(IT0) - INT0 is detected on falling edge when IT0 = 1; INT0 is detected as a low level when IT0 = 0.
//ARM EP1OUT
SYNCDELAY;
EP1OUTBC=0; //Set the BUSY bit in EP1OUTCS by writing any value to EP1OUTBC, arm the endpoint for EP1OUT transfer.
//The BUSY bit in EP1OUTCS, BUSY=1 means the SIE owns the buffer,
//BUSY=0 means that the firmware may read from or write the buffer.
//At power-on (or whenever a 0-to-1 transition occurs on the RESET pin), the BUSY
//bit is set to 0,
//Firware arms the endpoint for OUT transfers by writing any value to the
//byte count register EP1OUTBC, which automatically sets BUSY=1.
//BUSY is automatically cleared to 0 after the FX2 verifies the OUT data for
//accuracy and ACKs the transfer.
//A 1-to-0 BUSY transition asserts the EP1OUT interrupt request, signaling
//new EP1OUT data is availabe.
SYNCDELAY;
in_enable=FALSE;
}
void TD_Poll(void)
{
}
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 enumerated at high speed
SYNCDELAY; //
EP2AUTOINLENH = 0x02; // 0x02,set AUTOIN commit length to 512 bytes
SYNCDELAY; //
EP2AUTOINLENL = 0x00;
SYNCDELAY;
enum_high_speed = TRUE;
}
else
{ // FX2 enumerated at full speed
SYNCDELAY;
EP2AUTOINLENH = 0x00; // set AUTOIN commit length to 64 bytes
SYNCDELAY;
EP2AUTOINLENL = 0x40;
SYNCDELAY;
enum_high_speed = FALSE;
}
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);
}
#define VX_B1 0xB1 // reset the external FIFO
BOOL DR_VendorCmnd(void)
{
switch (SETUPDAT[1])
{
case VX_B1:
{
//start FPGA
OEA=0xfc; //1111 1100 // 1:turn on output buffer ; 0: turn off
SYNCDELAY;
IOA&=0xf7;
*EP0BUF=VX_B1;
EP0BCH=0;
EP0BCL=1;
EP0CS |= bmHSNAK;
break;
}
default:
return(TRUE);
}
return(FALSE);
}
//-----------------------------------------------------------------------------
// 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
{
// whenever we get a USB reset, we should revert to full speed mode
pConfigDscr = pFullSpeedConfigDscr;
((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;
pOtherConfigDscr = pHighSpeedConfigDscr;
((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;
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;
((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;
pOtherConfigDscr = pFullSpeedConfigDscr;
((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;
}
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
{ //the interrupt asserts when the host supplies a packet to the endpoint.(EP1-OUT has USB data)
if(in_enable==FALSE)
{ //if in_enable==false, this is the first EP1OUT transfer, so enable EP2 IN transfer
in_enable=TRUE;
SYNCDELAY;
// EP2CS &=0xFE; //Clear EP2 STALL bit.
SYNCDELAY;
IOA=0x80; //PORTA.3=0 release the FPGA.
//Reset EP2 FIFO
SYNCDELAY;
FIFORESET = 0x80; //Write 0x80 to this register to NAK all transfers from the host, then write 0x02, 0x04, 0x06, or 0x08
SYNCDELAY; //to reset an individual FIFO (i.e., to restore endpoint FIFO flags and byte counts to their default
FIFORESET = 0x02; //states), then write 0x00 to restore normal operation.
SYNCDELAY;
FIFORESET = 0x00;
}
while(EP24FIFOFLGS&0x04)
{ //waiting untill EP2FIFO Programable Flag is disasserted! (when it is idle for EP2 transfer)
;
}
EP1INBUF[0]=0x55;
SYNCDELAY;
EP1INBUF[1]=0xAA;
SYNCDELAY;
EP1INBC=2; //Arm EP1INBUF for IN-Transfer
//The BUSY bit in EP1INCS
//BUSY=1,means that the SIE "ownn" the buffer, so firmwave should not write (or read) the buffer.
//BUSY=0,means that the firmwave may write data into (or read from) the buffer.
//A 1-to-0 BUSY transition asserts the EP1IN interrupt request, signaling that the EP1IN buffer is
//free and ready to loaded with new data.
//The firmwave schedules an IN transfer by loading up to 64 bytes of data into EP1INBUF,
//then writing the byte count register EP1INBC with the number of bytes loaded.
//Writing the byte coun-register automatically sets BUSY=1.
//After the FX2 subsequently receives an IN token, sends the data, and successfully receives
//an ACK from the host, BUSY is automatically cleared to 0 to indicate that the buffer is ready
//to accept more data.
//After power-on, or whether a 0-to-1 transition occurs on the RESET pin, the BUSY bit is set to 0
SYNCDELAY;
SYNCDELAY;
EP1OUTBC=0; //Set the BUSY bit in EP1OUTCS by writing any value to EP1OUTBC; Arm the endpoint for EP1OUT transfer.
SYNCDELAY;
EZUSB_IRQ_CLEAR();
EPIRQ=0x08; //Clear the EP1out-USB IRQ bit by writing 1 to Bit-3. 0000 1000
}
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
{ //if EP2FIFOBUF is full, the error occurs!
in_enable=FALSE;
SYNCDELAY;
IOA=0x88; //PORTA.3=1 reset and suspend the FPGA.
// SYNCDELAY;
// EP2CS |=0x01; //Stall EP2.
SYNCDELAY; //EPxCFG where x=2,4,6,8
EP2CFG = 0xE8; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// VALID DIR TYPE1 TYPE0 SIZE 0 BUF1 BUF0
//DIR:0=OUT; 1=IN.
//TYPE[1:0], 00=Invalid, 01=ISOCHRONOUS, 10=BULK, 11=INTERRUPT
//SIZE: 0=512 bytes, 1=1024 bytes.
//BUF[1:0], 00=Quad, 01=Invalid, 10=Double, 11=Triple.
SYNCDELAY;
EXIF &=0xBF; //clear FIFO main interrupt request flag.
SYNCDELAY;
EP2FIFOIRQ=0x01; //**********EP2 Slave FIFO Flag Interrupt Request*********
// Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
// 0 0 0 0 0 PF Empty-Flag Full-Flag
}
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
{
}
void Setup_FLOWSTATE_Read ( void )
{
FLOWSTATE = FlowStates[18]; // 1000 0010b - FSE=1, FS[2:0]=002
SYNCDELAY;
FLOWEQ0CTL = FlowStates[20]; // CTL0 = 0 when flow condition equals zero (data flows)
SYNCDELAY;
FLOWEQ1CTL = FlowStates[21]; // CTL0 = 1 when flow condition equals one (data does not flow)
SYNCDELAY;
}
|