www.pudn.com > FX GPIF.zip > gfbrds.c


#pragma NOIV                    // Do not generate interrupt vectors 
//----------------------------------------------------------------------------- 
//  File:     gfbrds.c 
//  Contents: Hooks required to implement USB peripheral function. 
//            EZUSB FX GPIF firmware to "pass-on" USB pkts to/from slave. 
//  Copyright (c) 2001 Cypress Semiconductor All rights reserved 
//----------------------------------------------------------------------------- 
#include "ezusb.h" 
#include "ezregs.h" 
#include "Fx.h" 
 
extern BOOL GotSUD;             // Received setup data flag 
extern BOOL Sleep; 
 
// proto's from ...\gpif.c 
void GpifInit( void ); 
 
// local proto needed for BKPT LED address trigger 
void TD_Poll( void ); 
 
//----------------------------------------------------------------------------- 
// Global Variables 
//----------------------------------------------------------------------------- 
 
BYTE  Configuration;            // Current configuration 
BYTE  AlternateSetting;         // Alternate settings 
 
sbit PA0 = IOA ^ 0;             // GSTATE[ 0 ] 
sbit PA1 = IOA ^ 1;             // GSTATE[ 1 ] 
sbit PA2 = IOA ^ 2;             // GSTATE[ 2 ] 
sbit PA3 = IOA ^ 3; 
sbit PA6 = IOA ^ 6; 
sbit PA7 = IOA ^ 7; 
 
sbit PC0 = IOC ^ 0; 
sbit PC1 = IOC ^ 1; 
sbit PC2 = IOC ^ 2;             // INTO#, tied to slave PC3 pin, issue zerolenpkt 
sbit SHORTPKT = IOC ^ 3;        // tied to slave INT0# pin, issue shortpkt 
sbit PC4 = IOC ^ 4; 
sbit PC5 = IOC ^ 5; 
sbit PC6 = IOC ^ 6; 
sbit PC7 = IOC ^ 7; 
 
// ISR action needed flags, typically set via ISR, clr via foreground... 
BOOL zerolenpkt = 0;            // slave issued zerolenpkt 
                                // ...idle system service this event in ~8usec 
                                // ...busy system could take ~20usec or so... 
 
BOOL xfrvia_TD_Poll = 0;        // switch between TD_Poll() and VendorCmd() 
                                // ...also, used to sequence master/slave POR 
 
// Rev. D FX DK board, addr decode (movx reads only) via CPLD 
xdata volatile const unsigned char LED0_ON  _at_ 0x8000; 
xdata volatile const unsigned char LED0_OFF _at_ 0x8100; 
xdata volatile const unsigned char LED1_ON  _at_ 0x9000; 
xdata volatile const unsigned char LED1_OFF _at_ 0x9100; 
xdata volatile const unsigned char LED2_ON  _at_ 0xA000; 
xdata volatile const unsigned char LED2_OFF _at_ 0xA100; 
xdata volatile const unsigned char LED3_ON  _at_ 0xB000; 
xdata volatile const unsigned char LED3_OFF _at_ 0xB100; 
// it may be worth noting that by default the Keil mon-51 
// ...utility loads at 0xE000 and above 
 
// use this global (gfbrds.c) variable when (de)asserting debug LEDs... 
BYTE ledX_rdvar = 0x00; 
 
//----------------------------------------------------------------------------- 
// Task Dispatcher hooks 
//  The following hooks are called by the task dispatcher. 
//----------------------------------------------------------------------------- 
 
void TD_Init( void ) 
{ // Called once at startup 
 
  CPUCS &= 0xFD;                // don't drive CLKOUT (CLKOE=0) 
 
  PORTSETUP |= 0x01;            // use SFR, "mov" versions of PORT I/O 
 
  OEC = 0x08;                   // setup PC3 as an output, SHORTPKT 
  SHORTPKT = 1;                 // SHORTPKT -> high-low-high transition... 
 
  IN07VAL = 0x04;               // enable endp 2 IN 
  OUT07VAL = 0x04;              // enable endp 2 OUT 
  USBPAIR = 0x09;               // enable 2x buffering on both endp's 
 
  BPADDR = ( WORD )TD_Poll;     // set breakpoint to trigger on TD_Poll() 
  USBBAV |= 0x02;               // BPEN=1, enable breakpoint feature 
  USBBAV &= 0xFB;               // BPPULSE=0, disable breakpoint pulse mode 
 
  GpifInit( );                  // Configure GPIF from GPIFTool output file 
 
  IFCONFIG |= 0x08;             // GSTATE=1, drive GSTATE[2:0] out on PORTA[2:0] 
  // XCLKSEL pin determines if slave interface is: 
  // HIGH = sync (use XCLK pin to clock interface) or  
  // LOW = async (use internal 48MHz to clock interface) 
 
  ABSETUP |= 0x20;              //  GPIFTool issue with not setting ABSETUP.5=1(ASYNC) 
                                //    - when user selects -> 
                                //      - "Interface Timing      Async" 
 
  GPIFADRL = 0x00;              // gaddr[5:0] not used, asserts during GPIF WF 
  AINTC = 0x40;                 // tc=64, FITC=0 (set to max, tc for INs) 
  AOUTTC = 0x40;                // tc=64, FITC=0 (set to max, tc for OUTs) 
 
  PORTCCFG |= 0x04;             // alt. func INTO# 
// enable INTO# external pin interrupt, used by slave to issue SHORTPKT 
  EX0 = 1;                      // enable INT0# pin ISR 
  IT0 = 1;                      // configure INT0# pin, edge trigger 
 
  // turn debug LED[3:0] off... 
  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 BYTE AFIFOTC_OUT = 0x00; // store var for testing shortpkt 
  BYTE xfr = 0x00;                // dummy var for GPIF triggers 
 
  if( xfrvia_TD_Poll ) 
  { 
   
    // is the host sending data...OR is the fifo not empty 
    if( !( OUT2CS & 0x02 ) || !( ABOUTCS & 0x10 ) ) 
    { // OUT2BSY=0, when endp FIFO "not" empty, host sent pkt. 
      if( ABOUTCS & 0x10 ) 
      { // AOUTEF=1, when slave FIFO buffer available... 
        ledX_rdvar = LED0_ON; 
         
        // "pass-on" pkt. to master (GPIF) 
        DMALEN = OUT2BC; 
        if( DMALEN ) 
        { 
          DMASRC = &OUT2BUF;    // pointing to address of EP2OUT 
          DMADEST = &AOUTDATA;  // pointing to address of AOUTFIFO 
          EA = 0;               // protect against interrupts in Block0 
          DMAGO = 0xFF;         // dummy write to start xfr 
          while( !( DMAGO & 0x80 ) ) 
          {                     // this 8051 doesn't mind waiting here 
             ;                  // ... for DMADONE, ~1.5usec (64 bytes) 
          } 
          EA = 1;               // (re)enable interrupts... 
        } 
        else 
        { // Warning: DMA engine xfr's 256 bytes when DMALEN=0 
          // DO NOT DMA data, handle host sending zerolen OUT pkt to master... 
          SHORTPKT = 0; 
          AFIFOTC_OUT = 0x00; 
          SHORTPKT = 1;         // signal SHORTPKT to slave 
        } 
         
        OUT2BC = 0x00;          // (re)arm the endp 
      } 
      else 
      { // AOUTEF=0, when slave FIFO buffer "not" available (is "not-empty")... 
        if( IDLE_CS & 0x80 ) 
        { // if GPIF done then check slave status... 
          if( !( READY & 0x10 ) ) 
          { // RDY4=0, when slave is "not" FULL (tied to slave "full" flag) 
            AFIFOTC_OUT = AOUTBC; 
            AOUTTC = AOUTBC;    // tc=bc, FITC=0 
            // xfr pkt. to peripheral, via GPIF 
            ATRIG = AOUTBC;     // launch... AFIFO -> GPIF transaction(s) 
            if( AFIFOTC_OUT < 0x40 ) 
            { // handle short pkt. to slave, via PC3... 
              while( !( IDLE_CS & 0x80 ) ) 
              {                 // should take <15usec @ 8-bit async.  
                ;               // ~200nsec/write byte to slave... 
              } 
              SHORTPKT = 0;     // Needs to be >4 instr. cycles long... 
              AFIFOTC_OUT = 0x00; 
              SHORTPKT = 1;     // signal SHORTPKT to slave 
            } 
            else 
            { // was max pkt. size... 
               
            } 
          } 
          else 
          { // RDY4=1, when slave is FULL (tied to AINFF) 
             
          } 
        } 
        else 
        { // peripheral interface busy... 
           
        } 
      } 
    } 
    else 
    { // host is "not" sending data... 
      ledX_rdvar = LED0_OFF; 
    } 
 
    // does slave have data... OR do we already have data for the host... 
    if( IDLE_CS & 0x80 ) 
    { // if GPIF done then check slave status... 
     
      if( !( READY & 0x04 ) || !( ABINTF & 0x10 ) || ( zerolenpkt ) ) 
      { // RDY2=0, when slave "not" empty... (slave "not" empty flag, AOUTPF) 
        ledX_rdvar = LED1_ON; 
        if( (ABINTF & 0x10 ) && ( !zerolenpkt ) ) 
        { // AINEF=1, when buffer available... 
          // ...try to read 64 bytes (max pkt size) from slave 
           xfr = ATRIG;         // launch... GPIF -> AFIFO transaction(s) 
                                // should take <15usec @ 8-bit async... 
                                // ~200nsec/read byte from slave... 
        } 
        else 
        { 
          if( !( IN2CS & 0x02 ) ) 
          { // IN2BUSY=0 when buffer available... 
 
            DMALEN = AINBC; 
            if( DMALEN ) 
            { 
              DMASRC = &AINDATA;// pointing to address of AINFIFO 
              DMADEST = &IN2BUF;// pointing to address of EP2IN 
              EA = 0;           // protect against interrupts in Block0 
              DMAGO = 0xFF;     // dummy write to start xfr 
              while( !( DMAGO & 0x80 ) ) 
              {                 // this 8051 doesn't mind waiting here 
                 ;              // ... for DMADONE, ~1.5usec (64 bytes) 
              } 
              EA = 1;           // (re)enable interrupts... 
            } 
            else 
            { // DO NOT DMA the data... 
              // "shortpkt" should have already taken care of this... 
			        zerolenpkt = 0;           // clr action needed flag 
      		    EX0 = 1;                  // (re)enable INT0# pin ISR 
            } 
             
            IN2BC = DMALEN;     // arm endp, using bytes read via GPIF 
          } 
          else 
          { // if EP busy then host is behind... 
            // ...and we still have two buffers containing data 
          } 
        } 
      } 
      else 
      { // host has all the data the slave sent... 
        ledX_rdvar = LED1_OFF; 
      } 
    } 
    else 
    { // peripheral interface busy... 
       
    } 
  } 
  else 
  { // handle xfr via DR_VendorCmd 
     
  } 
   
  // turn off breakpoint LED 
  USBBAV |= 0x08; 
} 
 
BOOL TD_Suspend(void)       // Called before the device goes into suspend mode 
{ 
  // Turn off breakpoint light before entering suspend 
  USBBAV |= bmBREAK;       // Clear the breakpoint 
  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 
{ 
  Configuration = SETUPDAT[2]; 
  return(TRUE);        // Handled by user code 
} 
 
BOOL DR_GetConfiguration(void)  // Called when a Get Configuration command is received 
{ 
  IN0BUF[0] = Configuration; 
  EZUSB_SET_EP_BYTES(IN0BUF_ID,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 
{ 
  IN0BUF[0] = AlternateSetting; 
  EZUSB_SET_EP_BYTES(IN0BUF_ID,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_B0 0xB0  // abort GPIF 
#define VX_B1 0xB1  // flush/reset slave FIFOs 
#define VX_B2 0xB2  // handle data xfr via TD_Poll 
#define VX_B3 0xB3  // handle data xfr via DR_VendorCmd 
#define VX_B4 0xB4  // clear debug leds 
#define VX_B5 0xB5  // read aout fifo bc 
#define VX_B6 0xB6  // read DONE 
#define VX_B7 0xB7  // read aout fifo tc 
#define VX_B8 0xB8  // read ain fifo tc 
 
BOOL DR_VendorCmnd( void ) 
{ 
  switch( SETUPDAT[ 1 ] ) 
  { 
    case VX_B0: 
    { // ABORT GPIF waveform 
      ABORT = 0xFF; 
      *IN0BUF = 0xB0;           // return command type 
      break; 
    } 
    case VX_B1: 
    { // flush slave FIFOs 
      ABFLUSH = 0xFF; 
      *IN0BUF = 0xB1;           // return command type 
      break; 
    } 
    case VX_B2: 
    { // handle data xfr via TD_Poll 
      zerolenpkt = 0;           // clr flag, just in case one was pending 
	    EX0 = 1;                  // (re)enable INT0# pin ISR 
	    ledX_rdvar = LED3_OFF; 
      xfrvia_TD_Poll = 1; 
      *IN0BUF = 0xB2;           // return command type 
      break; 
    } 
    case VX_B3: 
    { // handle data xfr via DR_VendorCmd 
      xfrvia_TD_Poll = 0; 
      *IN0BUF = 0xB3;           // return command type 
      break; 
    } 
    case VX_B4: 
    { // clear debug leds 
      ledX_rdvar = LED0_OFF; 
      ledX_rdvar = LED1_OFF; 
      ledX_rdvar = LED2_OFF; 
      ledX_rdvar = LED3_OFF; 
      *IN0BUF = 0xB4;           // return command type 
      break; 
    } 
    case VX_B5: 
    { // read aout fifo bc 
      *IN0BUF = AOUTBC;         // return command type 
      break; 
    } 
    case VX_B6: 
    { // read DONE 
      *IN0BUF = IDLE_CS;         // return command type 
      break; 
    } 
    case VX_B7: 
    { // read aout fifo tc 
      *IN0BUF = AOUTTC;         // return command type 
      break; 
    } 
    case VX_B8: 
    { // read ain fifo tc 
      *IN0BUF = AINTC;          // return command type 
      break; 
    } 
    default: 
    { 
      break; 
    } 
  } 
  IN0BC = 0x01;                 // arm endp, # bytes to xfr 
  EP0CS |= bmBIT1;              // ack handshake phase of device request 
  return( FALSE );              // no errors, cmd handled okay 
} 
 
//----------------------------------------------------------------------------- 
// 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 
{ 
  EZUSB_IRQ_CLEAR(); 
  USBIRQ = bmURES;      // Clear URES IRQ 
} 
 
// ISR for the IN Bulk NAK (IBN) interrupt. 
void ISR_IBN(void) interrupt 0 
{ 
} 
 
void ISR_Susp(void) interrupt 0 
{ 
  Sleep = TRUE; 
  EZUSB_IRQ_CLEAR(); 
  USBIRQ = bmSUSP; 
} 
 
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_Ep2in(void) interrupt 0 
{ 
} 
 
void ISR_Ep2out( void ) interrupt 0 
{ 
} 
 
void ISR_Ep3in(void) interrupt 0 
{ 
} 
 
void ISR_Ep3out(void) interrupt 0 
{ 
} 
 
void ISR_Ep4in(void) interrupt 0 
{ 
} 
 
void ISR_Ep4out(void) interrupt 0 
{ 
} 
 
void ISR_Ep5in(void) interrupt 0 
{ 
} 
 
void ISR_Ep5out(void) interrupt 0 
{ 
} 
 
void ISR_Ep6in(void) interrupt 0 
{ 
} 
 
void ISR_Ep6out(void) interrupt 0 
{ 
} 
 
void ISR_Ep7in(void) interrupt 0 
{ 
} 
 
void ISR_Ep7out(void) interrupt 0 
{ 
} 
 
//----------------------------------------------------------------------------- 
// INT4 Interrupt Handlers 
//  The following functions are called by the INT4 interrupt jump table. 
//----------------------------------------------------------------------------- 
 
void ISR_AINPF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmAINPF;      // Clear AINPF IRQ 
} 
 
void ISR_AINEF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmAINEF;      // Clear AINEF IRQ 
} 
 
void ISR_AINFF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmAINFF;      // Clear AINFF IRQ 
} 
 
void ISR_BINPF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBINPF;      // Clear BINPF IRQ 
} 
 
void ISR_BINEF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBINEF;      // Clear BINEF IRQ 
} 
 
void ISR_BINFF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBINFF;      // Clear BINFF IRQ 
} 
 
void ISR_AOUTPF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABOUTIRQ = bmAOUTPF;    // Clear AOUTPF IRQ 
} 
 
void ISR_AOUTEF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmAOUTEF;      // Clear AOUTEF IRQ 
} 
 
void ISR_AOUTFF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmAOUTFF;      // Clear AOUTFF IRQ 
} 
 
void ISR_BOUTPF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBOUTPF;      // Clear BOUTPF IRQ 
} 
 
void ISR_BOUTEF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBOUTEF;      // Clear BOUTEF IRQ 
} 
 
void ISR_BOUTFF(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  ABINIRQ = bmBOUTFF;      // Clear BOUTFF IRQ 
} 
 
void ISR_GPIFDONE(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  GENIRQ = bmGPIFDONE;    // Clear GPIFDONE IRQ 
} 
 
void ISR_GPIFWF( void )  
interrupt 0 
{  // GPIF FIFORd WF detected slave empty 
  ABORT = 0xFF;              // abort to handle shortpkt 
 
  EXIF &=  ~0x40; 
  GENIRQ = bmGPIFWF;      // Clear GPIFWF IRQ 
//TGE  INT4CLR = 0xFF;    // need to first enable AUTOCLR feature... 
} 
 
void ISR_DMADONE(void) interrupt 0 
{ 
//  EXIF &=  ~0x40; 
//  GENIRQ = bmDMADONE;    // Clear DMADONE IRQ 
}