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