📄 periph.c
字号:
#pragma NOIV // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
// File: periph.c
// Contents: Hooks required to implement USB peripheral function.
//
// Copyright (c) 1997 AnchorChips, Inc. 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
#define DLADDR 0x0400 //Low data area start address
//#define DHADDR 0xf504 //High data area start address
//#define DHADDR_8 0xf600 //HIGHEST EIGHT DATA AREA SRART ADDRESS
#define DHADDR 0x0600 //High data area start address
//modify 10.06
#define CMDADDR 0x0002 //Command area start address
#define GPIF_FLGSELPF 0
#define GPIF_FLGSELEF 1
#define GPIF_FLGSELFF 2
#define GPIFTRIGWR 0
#define GPIFTRIGRD 4
#define GPIF_EP2 0
#define GPIF_EP4 1
#define GPIF_EP6 2
#define GPIF_EP8 3
// 512 for high speed, 64 for full speed
static WORD enum_pkt_size = 0x0000;
BOOL Flag_Of_Command; // Store command status
//WORD CmdLength = 0; // Command length
//WORD CmdAddress; // Current command Address
BOOL Flag_Of_DataHI; // Store last data area
BOOL FIRSTENTRY; // First Entry
BYTE FLAG_ENTRY;
int COUNT;
int cishu;
//BYTE ALREADY_READ; //WHEN selftest
// proto's from "gpif.c"
void GpifInit( void );
// Set Address GPIFADR[8:0] to PERIPHERAL
void Peripheral_SetAddress( WORD gaddr )
{
SYNCDELAY; //
GPIFADRH = gaddr >> 8;
SYNCDELAY; //
GPIFADRL = ( BYTE )gaddr; // setup GPIF address
}
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
void TD_Init(void) // Called once at startup
{
Rwuen = TRUE; // Enable remote-wakeup
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
SYNCDELAY;
// REVCTL = 0x01; // use enhanced packet handling
REVCTL = 0x03; //SET DYN_OUT=1,ENH_PKT=1
/* // EP1OUT BULK 00100000B
SYNCDELAY; // see TRM section 15.14
EP1OUTCFG = 0x20; // clear valid bit
// EP1IN BULK 00100000B
SYNCDELAY;
EP1INCFG = 0x20; // clear valid bit
*/
// EP2 512 BULK OUT 4x 10100000B
SYNCDELAY; // see TRM section 15.14
// EP2CFG = 0xA0; // BUF[1:0]=00 for 4x buffering
EP2CFG = 0xA2; // BUF[1:0]=00 for 2x buffering
// EP6 512 BULK IN 4x 11100000B
SYNCDELAY; //
//EP6CFG = 0xE0; // BUF[1:0]=00 for 4x buffering
EP6CFG = 0xE2; // BUF[1:0]=00 for 2x buffering
//10.06
// 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 to restore normal operation
// 8-bit bus (WORDWIDE=0)...
/*
SYNCDELAY; //
EP2FIFOCFG = 0x10; //AUTOOUT=1,WORDWIDE=0,ZEROLENIN=0
SYNCDELAY; //
EP6FIFOCFG = 0x08; //AUTOIN=1,WORDWIDE=0,ZEROLENIN=0
*/
SYNCDELAY; //
EP2FIFOCFG = 0x00;
// EP2FIFOCFG = 0x10; // EP2 is AUTOOUT=1, AUTOIN=0, ZEROLEN=0, WORDWIDE=0
SYNCDELAY; //
EP6FIFOCFG = 0x00;
//OUT endpoints do NOT come up armed
// SYNCDELAY;
// EP2BCL = 0x80; // arm first buffer by writing BC w/skip=1
// SYNCDELAY;
// EP2BCL = 0x80; // arm second buffer by writing BC w/skip=1
SYNCDELAY;
OUTPKTEND = 0x82; //ARM QUAD EP2 BUFFERS TO "PRIME THE PUMP"
SYNCDELAY;
OUTPKTEND = 0x82;
SYNCDELAY;
// OUTPKTEND = 0x82;
// SYNCDELAY;
// OUTPKTEND = 0x82;
// SYNCDELAY; //
/*
SYNCDELAY;
EP6AUTOINLENH = 0x02; //if AUTOIN=1,auto commit 512 byte packets
SYNCDELAY;
EP6AUTOINLENL = 0x00;
*/
// “all” EP2 buffers automatically arm when AUTOOUT
// 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)
// IN endp's come up in the cpu/peripheral domain
// setup INT4 as internal source for GPIF interrupts
// using INT4CLR (SFR), automatically enabled
/* INTSETUP |= 0x0B; // Enable INT4 FIFO/GPIF Autovectoring,Enable INT2
SYNCDELAY; // used here as "delay"
EXIF &= ~0x40; // just in case one was pending...CLEAR INT2,INT4
SYNCDELAY; // used here as "delay"
GPIFIRQ = 0x02; //GPIFWF=1,GPIFDONE=0
SYNCDELAY; //
GPIFIE = 0x02; // Enable GPIFWF interrupt
SYNCDELAY; //
EIE |= 0x05; // Enable INT4 ISR, EIE.2(EIEX4=1),Enable INT2
SYNCDELAY;
EPIE |= 0x10; //Enable ep2 ISR
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)
*/
// NAKIRQ |= ~bmIBN; // clear any pending PING-NAK IRQ
// NAKIE |= bmEP2PING; // enable the PING-NAK interrupt for EP2 and EP4
// ALREADY_READ = TRUE;
Flag_Of_Command = FALSE; //no command
// CmdAddress = CMDADDR; //command address initialed
Flag_Of_DataHI = TRUE; //data lies in high area
// Flag_Of_DataHI = FALSE; //data lies in LOW area
// FIRSTENTRY = TRUE;
// setup GPIF transaction count
SYNCDELAY;
GPIFTCB3 = 0x00;
SYNCDELAY;
GPIFTCB2 = 0x00;
SYNCDELAY;
GPIFTCB1 = 0x00;
SYNCDELAY;
GPIFTCB0 = 0x00;
PORTACFG = 0;
OEA = 0xFF; //USE PA.7 WHEN DEBUG
IOA = 0; //PA.7=1
COUNT = 0;
cishu = 0;
}
// EP2468STAT
// b7 b6 b5 b4 b3 b2 b1 b0
// EP8F EP8E EP6F EP6E EP4F EP4E EP2F EP2E
void TD_Poll(void) // Called repeatedly while the device is idle
{
// WORD DatAddress; //data address 10.06
// static WORD xFIFOTC_OUT = 0x0000;
// CmdAddress = CMDADDR; //command address initialed
// IOA = 0;
// is the host sending data...
if( !( EP2468STAT & 0x01 ) )
{
// IOA = 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;
OUTPKTEND = 0x02; // w/skip=0
SYNCDELAY;
// IOA = 0;
// EP2BCL = 0x80; // arm buffer by writing BC w/skip=1
// SYNCDELAY;
}
/* if( !( EP24FIFOFLGS & 0x02 ) )
{ // EP2EF=0 when FIFO “not” empty, host sent pkt.
SYNCDELAY;
OUTPKTEND = 0x02; // SKIP=0, pass buffer on to master
SYNCDELAY;
}*/
// 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
{
// IOA = 0x01;
// EF=0, when slave fifo is "not empty"
// ...the cpu passed the pkt. to the peripheral domain
// SYNCDELAY;
// OUTPKTEND = 0x02; // SKIP=0, pass buffer on to master
// SYNCDELAY;
// peripheral ALWAYS "not full"...
SYNCDELAY;
GPIFWFSELECT = 0xE4; //INITIAL WAVEFORM added at 10.06
Peripheral_SetAddress( CMDADDR );
// 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 = 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 < 512 )
// {
// handle short pkt. to peripheral
// wait for the transaction to terminate naturally...
SYNCDELAY;
while( !( GPIFTRIG & 0x80 ) )
{
// should take <75usec @ 8-bit async.
; // poll GPIFTRIG.7, DONE bit...
}
// SYNCDELAY;
// OUTPKTEND = 0x02; // SKIP=0, pass buffer on to master
// SYNCDELAY;
IOA = 0xFF;
COUNT = 0;
while(COUNT <2)
{
COUNT++;
}
IOA = 0;
// IOA = 0x01;
// ALREADY_READ = FALSE; when selftest
// signal "shortpkt" to peripheral peripheral here...
// }
// else
// {
// was max. pkt. size...
// ...let transaction terminate naturally...
// }
}
}
// else
// {
// DONE=0 when GPIF is "not" IDLE...
// }
/*
if( GPIFTRIG & 0x80 )
{
if( ALREADY_READ == FALSE )
{
if( EP68FIFOFLGS & 0x01 )
{
// EP6FF=1, when fifo "full"
}
else
{
// EP6FF=0, when fifo "not full", buffer available...
*/
/*
DatAddress = CMDADDR;
Peripheral_SetAddress( DatAddress );
// setup GPIF transaction count
SYNCDELAY;
EP6GPIFTCH = 0x01; //260
SYNCDELAY;
EP6GPIFTCL = 0x04;
SYNCDELAY;
// trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
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; // w/skip=0;.commit however many bytes in pkt.
SYNCDELAY; //
// ...NOTE: this also handles "shortpkt"
*/
/*
DatAddress = CMDADDR;
Peripheral_SetAddress( DatAddress );
// setup GPIF transaction count
SYNCDELAY;
EP6GPIFTCH = 0; //260-8=0xFC
SYNCDELAY;
EP6GPIFTCL = 0xFC;
SYNCDELAY;
// trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
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...
}
// DEAL WITH THE HIGH 8 BYTES
GPIFWFSELECT = 0xC6; //EIGHT BYTE READ EXCHANG FIFOREAD
DatAddress = 0xf0fe;
Peripheral_SetAddress( DatAddress );
// setup GPIF transaction count
SYNCDELAY;
EP6GPIFTCH = 0;
SYNCDELAY;
EP6GPIFTCL = 0x08;
SYNCDELAY;
// trigger FIFO read transaction(s), using SFR
// R/W=1, EP[1:0]=FIFO_EpNum for EPx read(s)
GPIFTRIG = GPIFTRIGRD | GPIF_EP6;
// wait for the transaction to terminate naturally...
SYNCDELAY; //
while( !( GPIFTRIG & 0x80 ) )
{
// should take <75usec @ 8-bit async.
; // poll GPIFTRIG.7, DONE bit...
}
GPIFWFSELECT = 0xE4; //INITIAL WAVEFORM
// EP6FIFOBUF[ 0 ] = REVID; //
// SYNCDELAY;
// EP6BCH = 0x00;
// SYNCDELAY;
// EP6BCL = 0x01; // pass src’d buffer on to host
// AUTOIN=0, so 8051 pass pkt. to host...
SYNCDELAY; //
INPKTEND = 0x06; // w/skip=0;.commit however many bytes in pkt.
SYNCDELAY; //
// ...NOTE: this also handles "shortpkt"
ALREADY_READ = TRUE;
}
}
}
*/
if( cishu > 0x03E8 ) //1000
{
cishu = 0;
IOA = 0xFF;
COUNT = 0;
while(COUNT <2)
{
COUNT++;
}
IOA = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -