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

📄 fw.c

📁 进行USB开发的外围设备固件程序
💻 C
字号:
//-----------------------------------------------------------------------------
//   File:      fw.c
//   Contents:   Firmware frameworks task dispatcher and device request parser
//            source.
//
// $Revision: 1 $
// $Date: 07/05/05 5:33p $
//
//   Copyright (c) 2005 Asia Science, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define DELAY_COUNT   0x9248*8L  // Delay for 8 sec at 24Mhz, 4 sec at 48
#define _IFREQ  48000            // IFCLK constant for Synchronization Delay
#define _CFREQ  48000            // CLKOUT constant for Synchronization Delay

//-----------------------------------------------------------------------------
// Random Macros
//-----------------------------------------------------------------------------
#define   min(a,b) (((a)<(b))?(a):(b))
#define   max(a,b) (((a)>(b))?(a):(b))

  // 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
  
#include "fx2sdly.h"             // Define _IFREQ and _CFREQ above this #include

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
volatile BOOL   GotSUD;
BOOL      Rwuen;
BOOL      Selfpwr;
volatile BOOL   Sleep;                  // Sleep mode enable flag

WORD   pDeviceDscr;   // Pointer to Device Descriptor; Descriptors may be moved
WORD   pDeviceQualDscr;
WORD   pHighSpeedConfigDscr;
WORD   pFullSpeedConfigDscr;   
WORD   pConfigDscr;
WORD   pOtherConfigDscr;   
WORD   pStringDscr;   

//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
BOOL TD_Suspend(void);
BOOL TD_Resume(void);

BOOL DR_GetDescriptor(void);
BOOL DR_SetConfiguration(void);
BOOL DR_GetConfiguration(void);
BOOL DR_SetInterface(void);
BOOL DR_GetInterface(void);
BOOL DR_GetStatus(void);
BOOL DR_ClearFeature(void);
BOOL DR_SetFeature(void);
BOOL DR_VendorCmnd(void);

void WRITE_DS1073();

// this table is used by the epcs macro 
const char code  EPCS_Offset_Lookup_Table[] =
{
   0,    // EP1OUT
   1,    // EP1IN
   2,    // EP2OUT
   2,    // EP2IN
   3,    // EP4OUT
   3,    // EP4IN
   4,    // EP6OUT
   4,    // EP6IN
   5,    // EP8OUT
   5,    // EP8IN
};

// macro for generating the address of an endpoint's control and status register (EPnCS)
#define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1)

//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------

// Task dispatcher
void main(void)
{
   DWORD   i;
   WORD   offset;
   DWORD   DevDescrLen;
   DWORD   j=0;
   WORD   IntDescrAddr;
   WORD   ExtDescrAddr;

   // Initialize Global States
   Sleep = FALSE;               // Disable sleep mode
   Rwuen = FALSE;               // Disable remote wakeup
   Selfpwr = FALSE;            // Disable self powered
   GotSUD = FALSE;               // Clear "Got setup data" flag

   // Initialize user device
   TD_Init();

   	//CLKOUT output float
	CPUCS &=0xfd;

	//USB CONNECT, although not necessary
	USBCS &= 0xf8;


	//set PA0/INT0 pin serve as PORT function ,not INT function as OUTPUT
	//PA1/INT1 the same
	PORTACFG &= 0xfc;
	
	//set PA0,PA1,PA3 as output.
	OEA = OEA|0x0b;

	//Reset PLD
	IOA &=0xf7;

	//set PA7/FLAGD/SLCS serve as FLAGD
	PORTACFG |= 0x80;

	//set PA3/WU2EN serve as PA3
	WAKEUPCS &= 0xfd;

	//set FD[15:0]/PD:PB serve as FD[15:0],not portD and PortB
	//and PA2/SLOE serve as SLOE, PA4/FIFOADD0 serve as FIFOADR0
	//and PA5/FIFOADD1 serve as FIFOADD1
	//and PA6/PKTEND serve as PKTEND 
	//and PA7/FLAGD/SLCS serve as not only PA7
	IFCONFIG |=0x03;

   // set the slave FIFO interface to 48MHz,default is 12MHZ
//   IFCONFIG |= 0x40;
	
   //set the slave FIFO as sync mode
   IFCONFIG &=0xf7;

   //Enable IFCLK output
   IFCONFIG |=0x20;

	//INVert polarity
   IFCONFIG |=0x10;

   //set IFCLK as internal source
	IFCONFIG |=0x80;

	//set DYN_OUT=1, ENH_PKT=1
	/*when DYN_OUT=0, the core automatically arms the endpoints when AUTOOUT is
	switched from 0 to 1. This means that firmware must reset the endpoint
	(and risk losing endpoint data) when switching between Auto-Out mode
	and Manual-Out mode.When DYN_OUT=1, the core disables auto-arming of
	the endpoints when AUTOOUT transitions from 0 to 1. This feature allows
	CPU intervention when switching between AUTO and Manual mode without having to
	reset the endpoint.
	Note: When DYN_OUT=1 and AUTOOUT=1, the CPU is responsible for 'priming the pump' 
	by initially arming the endpoints (OUTPKTEND w/SKIP=1 to pass packets to host)
	When ENH_PKT=0, the CPU can neither source OUT packets nor skip IN packets;
	it has only the following capabilities:
	OUT packets: Skip or Commit
	IN packets: Commit or Edit/Source
	When ENH_PKT=1, the CPU has additional capabilities:
	OUT packets: Skip, Commit, or Edit/Source
	IN packets: Skip, Commit, or Edit/Source*/

//	REVCTL = 0x03;
//	SYNCDELAY; 
	//Set FLAGS operate in INDEXed modes, 

	//FLAGA:'Programmable Full' flag for the FIFO indexed by FIFOADR[1:0]
	//and FLAGB: 'Full Flag' for the FIFO indexed
	PINFLAGSAB = 0x00;
	SYNCDELAY; 
	//FLAGC: 'Empty flag' for the FIFO indexed
	//and FLAGD : fixed as 'Programmable Full 'flag for EP2FIFO
	PINFLAGSCD = 0x00;
	SYNCDELAY; 
	
	//set FIFO flag pin polarity
	//PKTEND,SLWR,SLRD,SLOE,EF,FF all are 'ACTIVE LOW'
	FIFOPINPOLAR = 0x00;
	SYNCDELAY;
 
	// we are just using the default values, yes this is not necessary...
	//Valid,DIR,TYPE[1:0],
	EP2CFG = 0xA2;				//Valid ,Out,Bulk,512size,Double buffer
	SYNCDELAY;                    
	EP6CFG = 0xE2;				//Valid, In, Bulk,512size,double buffer
	SYNCDELAY;                    
	//RESET FIFOs(ep2 and ep6) Page340
	FIFORESET =0x80; // activate NAK-ALL to avoid race conditions
	SYNCDELAY; 
	FIFORESET =0x02;// reset, FIFO 2
	SYNCDELAY; 
	FIFORESET =0x06;// reset, FIFO 6
	SYNCDELAY; 
	FIFORESET =0x00;// deactivate NAK-ALL
	SYNCDELAY; 

	//set EP2 width to 8bit;
	EP2FIFOCFG &=0xfe;
	SYNCDELAY; 

	//set EP4 width to 8bit;
	EP4FIFOCFG &=0xfe;
	SYNCDELAY; 

	//set EP6 width to 8bit
  	EP6FIFOCFG &=0xfe;
  	SYNCDELAY; 

	//set FLAGB one sample earlier 
  	EP6FIFOCFG |=0x40;
  	SYNCDELAY; 

	//Enable ZERO packet 
  	EP6FIFOCFG |=0x04;
  	SYNCDELAY; 

  	//Enable EP6 AUTOIN 
  	EP6FIFOCFG |=0x08;
  	SYNCDELAY; 

	//set EP8 width to 8bit
  	EP8FIFOCFG &=0xfe;
  	SYNCDELAY; 

	//set FD8:15 as output
	OED=0xff;
	
	//Drive FD15 High
	IOD=0x80;

	//EPx AUTOIN packet length: 0x0200 in HighSped mode, and 0x0040 in fullspeed mode
	//These register can be used to set smaller packet sizes than the physical buffer size
    	EP6AUTOINLENH = 0x00;       // set core AUTO commit len = 64 bytes
	SYNCDELAY;                  // 
    	EP6AUTOINLENL = 0x40;
	SYNCDELAY;                  // 
 
	//For CPU mode,using this method to arm both Ep2 buffers
	EP2BCL = 0x80;                // arm EP2OUT by writing byte count w/skip.
	SYNCDELAY;                    
	EP2BCL = 0x80;
	SYNCDELAY;                    

	//set programmable Full Flag
	//EPxFIFOPFH and EPxFIFOPFL


   // The following section of code is used to relocate the descriptor table. 
   // Since the SUDPTRH and SUDPTRL are assigned the address of the descriptor 
   // table, the descriptor table must be located in on-part memory.
   // The 4K demo tools locate all code sections in external memory.
   // The descriptor table is relocated by the frameworks ONLY if it is found 
   // to be located in external memory.
   pDeviceDscr = (WORD)&DeviceDscr;
   pDeviceQualDscr = (WORD)&DeviceQualDscr;
   pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
   pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
   pStringDscr = (WORD)&StringDscr;

   if ((WORD)&DeviceDscr & 0xe000)
   {
      IntDescrAddr = INTERNAL_DSCR_ADDR;
      ExtDescrAddr = (WORD)&DeviceDscr;
      DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
      for (i = 0; i < DevDescrLen; i++)
         *((BYTE xdata *)IntDescrAddr+i) = 0xCD;
      for (i = 0; i < DevDescrLen; i++)
         *((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);
      pDeviceDscr = IntDescrAddr;
      offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
      pDeviceQualDscr -= offset;
      pConfigDscr -= offset;
      pOtherConfigDscr -= offset;
      pHighSpeedConfigDscr -= offset;
      pFullSpeedConfigDscr -= offset;
      pStringDscr -= offset;
   }

   EA = 0;                  // Diable 8051 interrupts

   CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)

   // clear the Sleep flag.
   	Sleep = FALSE;
  	
	//Write DS1073 MUX
	WRITE_DS1073();
	//output pa0=1,the relay on
	IOA |=0x01;
	//Power OFF LM2941	
	IOA |=0x02; 
	EZUSB_Delay(1000);
	//Power ON LM2941
	IOA &=0xfd; 
  
	while(1)
	{
	   TD_Poll();
	}
}

⌨️ 快捷键说明

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