⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpiftool.c

📁 The purpose of this code is to demonstrate how to get started using the GPIFTool utility in EZUSB F
💻 C
📖 第 1 页 / 共 2 页
字号:
#pragma NOIV                    // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
//   File:      gpiftool.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

// proto's from "gpif.c"
void GpifInit( void );

  // ...debug LEDs: accessed via movx reads only ( through CPLD )
xdata volatile const BYTE LED0_ON  _at_ 0x8000;
xdata volatile const BYTE LED0_OFF _at_ 0x8100;
xdata volatile const BYTE LED1_ON  _at_ 0x9000;
xdata volatile const BYTE LED1_OFF _at_ 0x9100;
xdata volatile const BYTE LED2_ON  _at_ 0xA000;
xdata volatile const BYTE LED2_OFF _at_ 0xA100;
xdata volatile const BYTE LED3_ON  _at_ 0xB000;
xdata volatile const BYTE LED3_OFF _at_ 0xB100;
  // it may be worth noting here that the default monitor loads at 0xC000

  // use this global variable when (de)asserting debug LEDs...
BYTE ledX_rdvar = 0x00;

// 512 for high speed, 64 for full speed
static WORD enum_pkt_size = 0x0000;    

//-----------------------------------------------------------------------------
// Task Dispatcher hooks
//   The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void TD_Init( void )
{ // Called once at startup

  CPUCS = 0x10;                 // CLKSPD[1:0]=10, for 48MHz operation
                                // CLKOE=0, don't drive CLKOUT
  
  GpifInit( );                  // init GPIF engine via GPIFTool output file

  // Registers which require a synchronization delay, see section 15.14
  // FIFORESET        FIFOPINPOLAR
  // INPKTEND         OUTPKTEND
  // EPxBCH:L         REVCTL
  // GPIFTCB3         GPIFTCB2
  // GPIFTCB1         GPIFTCB0
  // EPxFIFOPFH:L     EPxAUTOINLENH:L
  // EPxFIFOCFG       EPxGPIFFLGSEL
  // PINFLAGSxx       EPxFIFOIRQ
  // EPxFIFOIE        GPIFIRQ
  // GPIFIE           GPIFADRH:L
  // UDMACRCH:L       EPxGPIFTRIG
  // GPIFTRIG
  
  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
  //      ...these have been replaced by GPIFTC[B3:B0] registers
  
  // 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;
  
  // OUT endp's come up "unarmed" in the cpu domain
  // ...to "arm" the endp's when AUTOOUT=0 the cpu write's xBCL w/skip=1 (N times)
  SYNCDELAY;                    // 
  EP2BCL = 0x80;                // arm first buffer
  SYNCDELAY;                    // 
  EP2BCL = 0x80;                // arm second buffer
  SYNCDELAY;                    // 
  EP2BCL = 0x80;                // arm third buffer
  SYNCDELAY;                    // 
  EP2BCL = 0x80;                // arm fourth buffer
  
  // 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)
  
  // turn debug LED[3:0] off...
  ledX_rdvar = LED0_OFF;
  ledX_rdvar = LED1_OFF;
  ledX_rdvar = LED2_OFF;
  ledX_rdvar = LED3_OFF;
}

#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;
  
  // Registers which require a synchronization delay, see section 15.14
  // FIFORESET        FIFOPINPOLAR
  // INPKTEND         OUTPKTEND
  // EPxBCH:L         REVCTL
  // GPIFTCB3         GPIFTCB2
  // GPIFTCB1         GPIFTCB0
  // EPxFIFOPFH:L     EPxAUTOINLENH:L
  // EPxFIFOCFG       EPxGPIFFLGSEL
  // PINFLAGSxx       EPxFIFOIRQ
  // EPxFIFOIE        GPIFIRQ
  // GPIFIE           GPIFADRH:L
  // UDMACRCH:L       EPxGPIFTRIG
  // GPIFTRIG
  
  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
  //      ...these have been replaced by GPIFTC[B3:B0] registers


  // Handle OUT data...
  

  // is the host sending data...
  if( !( EP2468STAT & 0x01 ) )
  { 
    // EP2EF=0, when endp buffer "not" empty
    
    // ...at this point the pkt. switched from the usb domain to the cpu domain
    
    // if the host sent a pkt... then a buffer was available
    // AUTOOUT=0, so pass pkt. to peripheral domain - (GPIF)
    SYNCDELAY;          // 
    EP2BCL = 0x00;            // w/skip=0
    
  }
  else
  { 
    // host is "not" sending data...
  }    
  
  // is the peripheral interface idle...
  if( GPIFTRIG & 0x80 )
  { 
    // DONE=1, when GPIF is "idle"
  
    // check if there's a pkt in the peripheral domain...
    if( EP24FIFOFLGS & 0x02 )
    { 
      // ...EF=1 when buffer "empty", no more data to xfr.
    }    
    else
    { 
      // EF=0, when slave fifo is "not empty"
      // ...the cpu passed the pkt. to the peripheral domain
    
      // check if peripheral "not full"...
      if( GPIFREADYSTAT & 0x02 )
      { 
        // RDY1=1, when peripheral is "not" FULL (tied to peripheral "full" flag)
    
        xFIFOTC_OUT = ( ( EP2FIFOBCH << 8 ) + EP2FIFOBCL );
      
        // setup GPIF transaction count
        SYNCDELAY;            // 
        EP2GPIFTCH = EP2FIFOBCH;
        SYNCDELAY;
        EP2GPIFTCL = EP2FIFOBCL;  
        
        // trigger FIFO write transaction(s), using SFR
        // R/W=0, EP[1:0]=00 for EP2 write(s)
        SYNCDELAY;
        GPIFTRIG = GPIFTRIGWR | GPIF_EP2;  
      
        // NOTE: 512 bytes transfers in ~75usec on 8-bit async bus 
        // ...once master (GPIF) drains OUT pkt, it (re)arms to usb domain
        
        if( xFIFOTC_OUT < enum_pkt_size )
        { 
          // handle short pkt. to peripheral

          // wait for the transaction to terminate naturally...
          while( !( GPIFTRIG & 0x80 ) )
          { 
              // should take <75usec @ 8-bit async.
            ; // poll GPIFTRIG.7, DONE bit...
          }
          
          // signal "shortpkt" to peripheral peripheral here...
        }
        else
        { 
          // was max. pkt. size...
          // ...let transaction terminate naturally...
        }
      }
      else
      { 
        // RDY1=0, when peripheral is FULL
      }
    }
  }  
  else
  { 
    // DONE=0 when GPIF is "not" IDLE...
  }
  

  // Handle IN data...
  
  
  // is the peripheral interface idle...
  if( GPIFTRIG & 0x80 )
  { 
    // check if peripheral "not empty"...
    if( GPIFREADYSTAT & 0x01 )
    { 
      // RDY0=1, when peripheral "not" empty...
      
      if( EP68FIFOFLGS & 0x01 )
      { 
        // EP6FF=1, when fifo "full"
      }
      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 
        // NOTE: 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...
        }
        
       // AUTOIN=0, so 8051 pass pkt. to host...
        SYNCDELAY;              // 
        INPKTEND = 0x06;        // ...commit however many bytes in pkt.
                                // ...NOTE: this also handles "shortpkt"
        
      }
    }
    else
    { 
      // master has all the data the peripheral sent...
    }
  }
  else
  { 
    // peripheral interface busy...
  }
  
}

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -