📄 edgepf.c
字号:
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: edgepf.c
// Contents: Hooks required to implement USB peripheral function.
// Code demonstrates INT4 Autovector for slave fifo programmable
// flag ISR...
// 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
// EZUSB FX2 PORTA = slave fifo enable(s), when IFCFG[1:0]=11
sbit PA0 = IOA ^ 0; // alt. func., INT0#
sbit PA1 = IOA ^ 1; // alt. func., INT1#
// sbit PA2 = IOA ^ 2; // is SLOE
sbit PA3 = IOA ^ 3; // alt. func., WU2
// sbit PA4 = IOA ^ 4; // is FIFOADR0
// sbit PA5 = IOA ^ 5; // is FIFOADR1
// sbit PA6 = IOA ^ 6; // is PKTEND
// sbit PA7 = IOA ^ 7; // is FLAGD
// ...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;
#define REV_CTL
// comment out to fire isr on leading edge of programmable flag
#define EDGEPF_FALLING_EDGE_TRIGGER
//-----------------------------------------------------------------------------
// 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
IFCONFIG = 0xCB;
// IFCLKSRC=1 , FIFOs executes on internal clk source
// xMHz=1 , 48MHz internal clk rate
// IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
// IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
// ASYNC=1 , master samples asynchronous
// GSTATE=0 , Don't drive GPIF states out on PORTE[2:0], debug WF
// IFCFG[1:0]=11, FX2 in slave FIFO mode
// 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
// NOTE: The initialization sequence must be followed as outlined below
// ... for ISR's to fire:
// void ISR_Ep2pflag( void ) interrupt 0
// void ISR_Ep4pflag( void ) interrupt 0
// void ISR_Ep6pflag( void ) interrupt 0
// void ISR_Ep8pflag( void ) interrupt 0
#ifdef REV_CTL
SYNCDELAY; // see TRM section 15.14
REVCTL = 0x03; // use enhanced packet handling
#endif
// EPx 512 BULK OUT 2x
SYNCDELAY; //
EP2CFG = 0xA2; // BUF[1:0]=10 for 2x buffering
SYNCDELAY; //
EP4CFG = 0xA2; // BUF[1:0]=10 for 2x buffering
SYNCDELAY; //
EP6CFG = 0xA2; // BUF[1:0]=10 for 2x buffering
SYNCDELAY; //
EP8CFG = 0xA2; // BUF[1:0]=10 for 2x buffering
#ifdef EDGEPF_FALLING_EDGE_TRIGGER
SYNCDELAY; //
EP2FIFOPFH = 0x00; // PF ISR fires (f_edge) when BC>PF
SYNCDELAY; //
EP2FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP4FIFOPFH = 0x00; // PF ISR fires (f_edge) when BC>PF
SYNCDELAY; //
EP4FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP6FIFOPFH = 0x00; // PF ISR fires (f_edge) when BC>PF
SYNCDELAY; //
EP6FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP8FIFOPFH = 0x00; // PF ISR fires (f_edge) when BC>PF
SYNCDELAY; //
EP8FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
#else
SYNCDELAY; //
EP2FIFOPFH = 0x80; // PF ISR fires (l_edge) when BC>PF
SYNCDELAY; //
EP2FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP4FIFOPFH = 0x80; // PF ISR fires (l_edge) when BC>PF
SYNCDELAY; //
EP4FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP6FIFOPFH = 0x80; // PF ISR fires (l_edge) when BC>PF
SYNCDELAY; //
EP6FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
EP8FIFOPFH = 0x80; // PF ISR fires (l_edge) when BC>PF
SYNCDELAY; //
EP8FIFOPFL = 0x01; // PF=1
SYNCDELAY; //
#endif
// setup INT4 as internal source for GPIF/FIFO 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"
EIE |= 0x04; // Enable INT4 ISR, EIE.2(EIEX4=1)
// EA = 1; // EA is enabled in "fw.c" after TD_Init( ); gets called...
SYNCDELAY; //
EP2FIFOIRQ = 0x00; // clear latch
SYNCDELAY; //
EP4FIFOIRQ = 0x00; //
SYNCDELAY; //
EP6FIFOIRQ = 0x00; //
SYNCDELAY; //
EP8FIFOIRQ = 0x00; //
#ifdef EDGEPF_FALLING_EDGE_TRIGGER
SYNCDELAY; //
EP2FIFOIE = 0x0C; // EDGEPF=1, enable PF
SYNCDELAY; //
EP4FIFOIE = 0x0C; // EDGEPF=1, enable PF
SYNCDELAY; //
EP6FIFOIE = 0x0C; // EDGEPF=1, enable PF
SYNCDELAY; //
EP8FIFOIE = 0x0C; // EDGEPF=1, enable PF
#else
SYNCDELAY; //
EP2FIFOIE = 0x04; // EDGEPF=0, enable PF
SYNCDELAY; //
EP4FIFOIE = 0x04; // EDGEPF=0, enable PF
SYNCDELAY; //
EP6FIFOIE = 0x04; // EDGEPF=0, enable PF
SYNCDELAY; //
EP8FIFOIE = 0x04; // EDGEPF=0, enable PF
#endif
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
// init manual out mode...
SYNCDELAY; //
EP2FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0
SYNCDELAY; //
EP4FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0
SYNCDELAY; //
EP6FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0
SYNCDELAY; //
EP8FIFOCFG = 0x00; // AUTOOUT=0, WORDWIDE=0
#ifdef REV_CTL
SYNCDELAY; //
OUTPKTEND = 0x82; // arm first buffer
SYNCDELAY; //
OUTPKTEND = 0x82; // arm second buffer
SYNCDELAY; //
OUTPKTEND = 0x82; // arm third buffer
SYNCDELAY; //
OUTPKTEND = 0x82; // arm fourth buffer
SYNCDELAY; //
OUTPKTEND = 0x84; // arm first buffer
SYNCDELAY; //
OUTPKTEND = 0x84; // arm second buffer
SYNCDELAY; //
OUTPKTEND = 0x84; // arm third buffer
SYNCDELAY; //
OUTPKTEND = 0x84; // arm fourth buffer
SYNCDELAY; //
OUTPKTEND = 0x86; // arm first buffer
SYNCDELAY; //
OUTPKTEND = 0x86; // arm second buffer
SYNCDELAY; //
OUTPKTEND = 0x86; // arm third buffer
SYNCDELAY; //
OUTPKTEND = 0x86; // arm fourth buffer
SYNCDELAY; //
OUTPKTEND = 0x88; // arm first buffer
SYNCDELAY; //
OUTPKTEND = 0x88; // arm second buffer
SYNCDELAY; //
OUTPKTEND = 0x88; // arm third buffer
SYNCDELAY; //
OUTPKTEND = 0x88; // arm fourth buffer
#else
SYNCDELAY; //
EP2BCL = 0x80;
SYNCDELAY; //
EP2BCL = 0x80;
SYNCDELAY; //
EP2BCL = 0x80;
SYNCDELAY; //
EP2BCL = 0x80;
SYNCDELAY; //
EP4BCL = 0x80;
SYNCDELAY; //
EP4BCL = 0x80;
SYNCDELAY; //
EP4BCL = 0x80;
SYNCDELAY; //
EP4BCL = 0x80;
SYNCDELAY; //
EP6BCL = 0x80;
SYNCDELAY; //
EP6BCL = 0x80;
SYNCDELAY; //
EP6BCL = 0x80;
SYNCDELAY; //
EP6BCL = 0x80;
SYNCDELAY; //
EP8BCL = 0x80;
SYNCDELAY; //
EP8BCL = 0x80;
SYNCDELAY; //
EP8BCL = 0x80;
SYNCDELAY; //
EP8BCL = 0x80;
#endif
}
void TD_Poll( void )
{ // Called repeatedly while the device is idle
// ...nothing to do... slave fifo's are in AUTO mode...
// ...note: all four debug LED[3:0]s will be on after code download
// ......please send vend_cmnd of 0xB2 to clear LEDs before testing
// ...once the user sends vend_cmnd 0xC7...
// ......core "auto" commits OUT pkts
}
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
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_B2 0xB2 // turn OFF debug LEDs...
#define VX_B7 0xB7 // re-initialize, call TD_Init( );
#define VX_B8 0xB8 // do a "soft reset", vector to org 00h
#define VX_B9 0xB9 // commit out pkt. old way
#define VX_BA 0xBA // commit out pkt. new way
#define VX_BB 0xBB // commit in pkt. new way
#define VX_BC 0xBC // skip in pkt. new way
#define VX_BD 0xBD // cpu change len. out pkt
#define VX_BE 0xBE // cpu change len. in pkt
#define VX_BF 0xBF // skip out pkt. new way
#define VX_C2 0xC2 // source out pkt.
#define VX_C6 0xC6 // use dynamic out mode
#define VX_C7 0xC7 // use autoout=1
#define VX_C8 0xC8 // use autoout=0
#define VX_C9 0xC9 // reset all fifo's
#define VX_CA 0xCA // don't use enh_pkt or dyn_out
#define VX_D2 0xD2 // skip OUT pkt
#define VX_D4 0xD4 // skip OUT pkt
#define VX_D6 0xD6 // skip OUT pkt
#define VX_D8 0xD8 // skip OUT pkt
// 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
BOOL DR_VendorCmnd( void )
{
// 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
switch( SETUPDAT[ 1 ] )
{
case VX_B2:
{ // turn OFF debug LEDs...
ledX_rdvar = LED0_OFF; // visual
ledX_rdvar = LED1_OFF; // visual
ledX_rdvar = LED2_OFF; // visual
ledX_rdvar = LED3_OFF; // visual
*EP0BUF = VX_B2;
break;
}
case VX_B7:
{
TD_Init( );
*EP0BUF = VX_B7;
break;
}
case VX_B8:
{
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
SYNCDELAY; // used here as "delay"
SYNCDELAY; // used here as "delay"
EA = 0;
// ...do a "soft" code only RESET... vector to ORG 0x0000
( ( void ( code * ) ( void ) ) 0x0000 ) ( );
*EP0BUF = VX_B8;
break;
}
case VX_B9:
{
#ifdef REV_CTL
SYNCDELAY;
EP2BCL = 0x00; // commit out pkt, old way.. w/skip=0
SYNCDELAY;
#else
SYNCDELAY;
EP2BCL = 0x00; // commit out pkt, old way.. w/skip=0
SYNCDELAY;
#endif
*EP0BUF = VX_B9;
break;
}
case VX_BA:
{
SYNCDELAY;
OUTPKTEND = 0x02; // commit out pkt, new way.. w/skip=0
SYNCDELAY;
*EP0BUF = VX_BA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -