www.pudn.com > EZ-USB HID Keyboard.zip > fw.c


//----------------------------------------------------------------------------- 
//	File:		fw.c 
//	Contents:	Firmware frameworks task dispatcher and device request parser 
//				source. 
// 
//	Copyright (c) 1997 AnchorChips, Inc. All rights reserved 
//----------------------------------------------------------------------------- 
#include "ezusb.h" 
#include "ezregs.h" 
 
//----------------------------------------------------------------------------- 
// Random Macros 
//----------------------------------------------------------------------------- 
#define	min(a,b) (((a)<(b))?(a):(b)) 
#define	max(a,b) (((a)>(b))?(a):(b)) 
 
//----------------------------------------------------------------------------- 
// Constants 
//----------------------------------------------------------------------------- 
 
//----------------------------------------------------------------------------- 
// 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	pConfigDscr;	 
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); 
 
//----------------------------------------------------------------------------- 
// 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(); 
 
	// 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; 
	pConfigDscr = (WORD)&ConfigDscr; 
	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; 
		pConfigDscr -= offset; 
		pStringDscr -= offset; 
	} 
 
	EZUSB_IRQ_ENABLE();				// Enable USB interrupt (INT2) 
	EZUSB_ENABLE_RSMIRQ();				// Wake-up interrupt 
 
	// The 8051 is responsible for all USB events, even those that have happened 
	// before this point.  We cannot ignore pending USB interrupts. 
	// The chip will come out of reset with the flags all cleared. 
	//	USBIRQ = 0xff;				// Clear any pending USB interrupt requests 
	PORTCCFG |= 0xc0;				// Turn on r/w lines for external memory  
 
	USBBAV = USBBAV | 1 & ~bmBREAK;	// Disable breakpoints and autovectoring 
	USBIEN |= bmSUDAV | bmSUTOK | bmSUSP | bmURES;	// Enable selected interrupts 
	EA = 1;						// Enable 8051 interrupts 
 
   #ifndef NO_RENUM 
   // Note: at full speed, high speed hosts may take 5 sec to detect device 
   EZUSB_Discon(TRUE); // Renumerate 
   #endif 
 
 
	CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration) 
 
	// Task Dispatcher 
	while(TRUE)					// Main Loop 
	{ 
		if(GotSUD)				// Wait for SUDAV 
		{ 
			SetupCommand();	 		// Implement setup command 
  			GotSUD = FALSE;		   	// Clear SUDAV flag 
		} 
 
		// Poll User Device 
		// NOTE: Idle mode stops the processor clock.  There are only two 
		// ways out of idle mode, the WAKEUP pin, and detection of the USB 
		// resume state on the USB bus.  The timers will stop and the 
		// processor will not wake up on any other interrupts. 
		if (Sleep) 
		    { 
    		if(TD_Suspend()) 
    		    {  
    		    Sleep = FALSE;	   		// Clear the "go to sleep" flag.  Do it here to prevent any race condition between wakeup and the next sleep. 
    		    do 
    		        { 
       			    EZUSB_Susp();			// Place processor in idle mode. 
    		        } 
                while(!Rwuen && EZUSB_EXTWAKEUP()); 
                // Must continue to go back into suspend if the host has disabled remote wakeup 
                // *and* the wakeup was caused by the external wakeup pin. 
                 
    			// 8051 activity will resume here due to USB bus or Wakeup# pin activity. 
    			EZUSB_Resume();	// If source is the Wakeup# pin, signal the host to Resume.		 
    			TD_Resume(); 
    		    }    
		    } 
		TD_Poll(); 
	} 
} 
 
// Device request parser 
void SetupCommand(void) 
{ 
	void	*dscr_ptr; 
	DWORD	i; 
 
	switch(SETUPDAT[1]) 
	{ 
		case SC_GET_DESCRIPTOR:						// *** Get Descriptor 
			if(DR_GetDescriptor()) 
				switch(SETUPDAT[3])			 
				{ 
					case GD_DEVICE:				// Device 
						SUDPTRH = MSB(pDeviceDscr); 
						SUDPTRL = LSB(pDeviceDscr); 
						break; 
					case GD_CONFIGURATION:			// Configuration 
						if(dscr_ptr = (void *)EZUSB_GetConfigDscr(SETUPDAT[2])) 
						{ 
							SUDPTRH = MSB(dscr_ptr); 
							SUDPTRL = LSB(dscr_ptr); 
						} 
						else 
							EZUSB_STALL_EP0(); 	// Stall End Point 0 
						break; 
					case GD_STRING:				// String 
						if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2])) 
						{ 
							// Workaround for rev D errata number 8 
							// If you're certain that you will never run on rev D, 
							// you can just do this: 
							// SUDPTRH = MSB(dscr_ptr); 
							// SUDPTRL = LSB(dscr_ptr); 
							STRINGDSCR *sdp; 
							BYTE len; 
 
							sdp = dscr_ptr; 
 
							len = sdp->length; 
							if (len > SETUPDAT[6])  
								len = SETUPDAT[6]; //limit to the requested length 
							 
							while (len) 
							{ 
								for(i=0; i