?? fw.c
字號:
//-----------------------------------------------------------------------------// File: fw.c// Contents: Firmware frameworks task dispatcher and device request parser// source.//// indent 3. NO TABS!//// $Revision: 1.1 $// $Date: 2006/04/09 08:38:17 $//// Copyright (c) 1997 AnchorChips, 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 flagWORD pDeviceDscr; // Pointer to Device Descriptor; Descriptors may be movedWORD 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);// 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 dispatchervoid 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; 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; } EZUSB_IRQ_ENABLE(); // Enable USB interrupt (INT2) EZUSB_ENABLE_RSMIRQ(); // Wake-up interrupt INTSETUP |= (bmAV2EN | bmAV4EN); // Enable INT 2 & 4 autovectoring USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; // Enable selected interrupts EA = 1; // Enable 8051 interrupts#ifndef NO_RENUM // Renumerate if necessary. Do this by checking the renum bit. If it // is already set, there is no need to renumerate. The renum bit will // already be set if this firmware was loaded from an eeprom. if(!(USBCS & bmRENUM)) { EZUSB_Discon(TRUE); // renumerate }#endif // unconditionally re-connect. If we loaded from eeprom we are // disconnected and need to connect. If we just renumerated this // is not necessary but doesn't hurt anything USBCS &=~bmDISCON; CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration) // clear the Sleep flag. Sleep = FALSE; // 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 parservoid SetupCommand(void){ void *dscr_ptr; 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_DEVICE_QUALIFIER: // Device Qualifier SUDPTRH = MSB(pDeviceQualDscr); SUDPTRL = LSB(pDeviceQualDscr); break; case GD_CONFIGURATION: // Configuration SUDPTRH = MSB(pConfigDscr); SUDPTRL = LSB(pConfigDscr); break; case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration SUDPTRH = MSB(pOtherConfigDscr); SUDPTRL = LSB(pOtherConfigDscr); break; case GD_STRING: // String if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2])) { SUDPTRH = MSB(dscr_ptr); SUDPTRL = LSB(dscr_ptr); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; default: // Invalid request EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_GET_INTERFACE: // *** Get Interface DR_GetInterface(); break; case SC_SET_INTERFACE: // *** Set Interface DR_SetInterface(); break; case SC_SET_CONFIGURATION: // *** Set Configuration DR_SetConfiguration(); break; case SC_GET_CONFIGURATION: // *** Get Configuration DR_GetConfiguration(); break; case SC_GET_STATUS: // *** Get Status if(DR_GetStatus()) switch(SETUPDAT[0]) { case GS_DEVICE: // Device EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_INTERFACE: // Interface EP0BUF[0] = 0; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_ENDPOINT: // End Point EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; default: // Invalid Command EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_CLEAR_FEATURE: // *** Clear Feature if(DR_ClearFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = FALSE; // Disable Remote Wakeup else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point if(SETUPDAT[2] == 0) { *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL; EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] ); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; } break; case SC_SET_FEATURE: // *** Set Feature if(DR_SetFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = TRUE; // Enable Remote Wakeup else if(SETUPDAT[2] == 2) // Set Feature Test Mode. The core handles this request. However, it is // necessary for the firmware to complete the handshake phase of the // control transfer before the chip will enter test mode. It is also // necessary for FX2 to be physically disconnected (D+ and D-) // from the host before it will enter test mode. break; else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL; break; } break; default: // *** Invalid Command if(DR_VendorCmnd()) EZUSB_STALL_EP0(); // Stall End Point 0 } // Acknowledge handshake phase of device request EP0CS |= bmHSNAK;}// Wake-up interrupt handlervoid resume_isr(void) interrupt WKUP_VECT{ EZUSB_CLEAR_RSMIRQ();}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -