C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 1   


C51 COMPILER V7.07, COMPILATION OF MODULE FW
OBJECT MODULE PLACED IN fw.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE fw.c BROWSE DEBUG OBJECTEXTEND

stmt level    source

   1          //-----------------------------------------------------------------------------
   2          //   File:      fw.c
   3          //   Contents:  Firmware frameworks task dispatcher and device request parser
   4          //
   5          // $Archive: /USB/Examples/FX2LP/bulkext/fw.c $
   6          // $Date: 3/23/05 2:53p $
   7          // $Revision: 8 $
   8          //
   9          //
  10          //-----------------------------------------------------------------------------
  11          // Copyright 2003, Cypress Semiconductor Corporation
  12          //-----------------------------------------------------------------------------
  13          #include "fx2.h"
  14          #include "fx2regs.h"
  15          #include "syncdly.h"            // SYNCDELAY macro
  16          
  17          //-----------------------------------------------------------------------------
  18          // Constants
  19          //-----------------------------------------------------------------------------
  20          #define DELAY_COUNT   0x9248*8L  // Delay for 8 sec at 24Mhz, 4 sec at 48
  21          #define _IFREQ  48000            // IFCLK constant for Synchronization Delay
  22          #define _CFREQ  48000            // CLKOUT constant for Synchronization Delay
  23          
  24          //-----------------------------------------------------------------------------
  25          // Random Macros
  26          //-----------------------------------------------------------------------------
  27          #define   min(a,b) (((a)<(b))?(a):(b))
  28          #define   max(a,b) (((a)>(b))?(a):(b))
  29          
  30          //-----------------------------------------------------------------------------
  31          // Global Variables
  32          //-----------------------------------------------------------------------------
  33          volatile BOOL   GotSUD;
  34          BOOL      Rwuen;
  35          BOOL      Selfpwr;
  36          volatile BOOL   Sleep;                  // Sleep mode enable flag
  37          
  38          WORD   pDeviceDscr;   // Pointer to Device Descriptor; Descriptors may be moved
  39          WORD   pDeviceQualDscr;
  40          WORD   pHighSpeedConfigDscr;
  41          WORD   pFullSpeedConfigDscr;   
  42          WORD   pConfigDscr;
  43          WORD   pOtherConfigDscr;   
  44          WORD   pStringDscr;   
  45          
  46          //-----------------------------------------------------------------------------
  47          // Prototypes
  48          //-----------------------------------------------------------------------------
  49          void SetupCommand(void);
  50          void TD_Init(void);
  51          void TD_Poll(void);
  52          BOOL TD_Suspend(void);
  53          BOOL TD_Resume(void);
  54          
  55          BOOL DR_GetDescriptor(void);
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 2   

  56          BOOL DR_SetConfiguration(void);
  57          BOOL DR_GetConfiguration(void);
  58          BOOL DR_SetInterface(void);
  59          BOOL DR_GetInterface(void);
  60          BOOL DR_GetStatus(void);
  61          BOOL DR_ClearFeature(void);
  62          BOOL DR_SetFeature(void);
  63          BOOL DR_VendorCmnd(void);
  64          
  65          // this table is used by the epcs macro 
  66          const char code  EPCS_Offset_Lookup_Table[] =
  67          {
  68             0,    // EP1OUT
  69             1,    // EP1IN
  70             2,    // EP2OUT
  71             2,    // EP2IN
  72             3,    // EP4OUT
  73             3,    // EP4IN
  74             4,    // EP6OUT
  75             4,    // EP6IN
  76             5,    // EP8OUT
  77             5,    // EP8IN
  78          };
  79          
  80          // macro for generating the address of an endpoint's control and status register (EPnCS)
  81          #define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1)
  82          
  83          //-----------------------------------------------------------------------------
  84          // Code
  85          //-----------------------------------------------------------------------------
  86          
  87          // Task dispatcher
  88          void main(void)
  89          {
  90   1         DWORD   i;
  91   1         WORD   offset;
  92   1         DWORD   DevDescrLen;
  93   1         DWORD   j=0;
  94   1         WORD   IntDescrAddr;
  95   1         WORD   ExtDescrAddr;
  96   1      
  97   1         // Initialize Global States
  98   1         Sleep = FALSE;               // Disable sleep mode
  99   1         Rwuen = FALSE;               // Disable remote wakeup
 100   1         Selfpwr = FALSE;            // Disable self powered
 101   1         GotSUD = FALSE;               // Clear "Got setup data" flag
 102   1      
 103   1         // Initialize user device
 104   1         TD_Init();
 105   1      
 106   1         // The following section of code is used to relocate the descriptor table. 
 107   1         // The frameworks uses SUDPTRH and SUDPTRL to automate the SETUP requests
 108   1         // for descriptors.  These registers only work with memory locations
 109   1         // in the EZ-USB internal RAM.  Therefore, if the descriptors are located
 110   1         // in external RAM, they must be copied to in internal RAM.  
 111   1         // The descriptor table is relocated by the frameworks ONLY if it is found 
 112   1         // to be located in external memory.
 113   1         pDeviceDscr = (WORD)&DeviceDscr;
 114   1         pDeviceQualDscr = (WORD)&DeviceQualDscr;
 115   1         pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
 116   1         pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
 117   1         pStringDscr = (WORD)&StringDscr;
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 3   

 118   1      
 119   1         // Is the descriptor table in external RAM (> 16Kbytes)?  If yes,
 120   1         // then relocate.
 121   1         // Note that this code only checks if the descriptors START in 
 122   1         // external RAM.  It will not work if the descriptor table spans
 123   1         // internal and external RAM.
 124   1         if ((WORD)&DeviceDscr & 0xC000)
 125   1         {
 126   2            // first, relocate the descriptors
 127   2            IntDescrAddr = INTERNAL_DSCR_ADDR;
 128   2            ExtDescrAddr = (WORD)&DeviceDscr;
 129   2            DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
 130   2            for (i = 0; i < DevDescrLen; i++)
 131   2               *((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);
 132   2      
 133   2            // update all of the descriptor pointers
 134   2            pDeviceDscr = IntDescrAddr;
 135   2            offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
 136   2            pDeviceQualDscr -= offset;
 137   2            pConfigDscr -= offset;
 138   2            pOtherConfigDscr -= offset;
 139   2            pHighSpeedConfigDscr -= offset;
 140   2            pFullSpeedConfigDscr -= offset;
 141   2            pStringDscr -= offset;
 142   2         }
 143   1      
 144   1         EZUSB_IRQ_ENABLE();            // Enable USB interrupt (INT2)
 145   1         EZUSB_ENABLE_RSMIRQ();            // Wake-up interrupt
 146   1      
 147   1         INTSETUP |= (bmAV2EN | bmAV4EN);     // Enable INT 2 & 4 autovectoring
 148   1      
 149   1         USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT;   // Enable selected interrupts
 150   1         EA = 1;                  // Enable 8051 interrupts
 151   1      
 152   1      #ifndef NO_RENUM
 153   1         // Renumerate if necessary.  Do this by checking the renum bit.  If it
 154   1         // is already set, there is no need to renumerate.  The renum bit will
 155   1         // already be set if this firmware was loaded from an eeprom.
 156   1         if(!(USBCS & bmRENUM))
 157   1         {
 158   2             EZUSB_Discon(TRUE);   // renumerate
 159   2         }
 160   1      #endif
 161   1      
 162   1         // unconditionally re-connect.  If we loaded from eeprom we are
 163   1         // disconnected and need to connect.  If we just renumerated this
 164   1         // is not necessary but doesn't hurt anything
 165   1         USBCS &=~bmDISCON;
 166   1      
 167   1         CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch
 168   1      
 169   1         // clear the Sleep flag.
 170   1         Sleep = FALSE;
 171   1      
 172   1         // Task Dispatcher
 173   1         while(TRUE)               // Main Loop
 174   1         {
 175   2            // Poll User Device
 176   2            TD_Poll();
 177   2      
 178   2            // Check for pending SETUP
 179   2            if(GotSUD)
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 4   

 180   2            {
 181   3               SetupCommand();          // Implement setup command
 182   3               GotSUD = FALSE;          // Clear SETUP flag
 183   3            }
 184   2      
 185   2            // check for and handle suspend.
 186   2            // NOTE: Idle mode stops the processor clock.  There are only two
 187   2            // ways out of idle mode, the WAKEUP pin, and detection of the USB
 188   2            // resume state on the USB bus.  The timers will stop and the
 189   2            // processor will not wake up on any other interrupts.
 190   2            if (Sleep)
 191   2            {
 192   3               if(TD_Suspend())
 193   3               { 
 194   4                  Sleep = FALSE;     // Clear the "go to sleep" flag.  Do it here to prevent any race condition 
             -between wakeup and the next sleep.
 195   4                  do
 196   4                  {
 197   5                     EZUSB_Susp();         // Place processor in idle mode.
 198   5                  }
 199   4                  while(!Rwuen && EZUSB_EXTWAKEUP());
 200   4                  // above.  Must continue to go back into suspend if the host has disabled remote wakeup
 201   4                  // *and* the wakeup was caused by the external wakeup pin.
 202   4      
 203   4                  // 8051 activity will resume here due to USB bus or Wakeup# pin activity.
 204   4                  EZUSB_Resume();   // If source is the Wakeup# pin, signal the host to Resume.      
 205   4                  TD_Resume();
 206   4               }   
 207   3            }
 208   2      
 209   2         }
 210   1      }
 211          
 212          BOOL HighSpeedCapable()
 213          {
 214   1         // this function determines if the chip is high-speed capable.
 215   1         // FX2 and FX2LP are high-speed capable. FX1 is not - it does
 216   1         // not have a high-speed transceiver.
 217   1      
 218   1         if (GPCR2 & bmFULLSPEEDONLY)
 219   1            return FALSE;
 220   1         else
 221   1            return TRUE;
 222   1      }   
 223          
 224          // Device request parser
 225          void SetupCommand(void)
 226          {
 227   1         void   *dscr_ptr;
 228   1      
 229   1         switch(SETUPDAT[1])
 230   1         {
 231   2            case SC_GET_DESCRIPTOR:                  // *** Get Descriptor
 232   2               if(DR_GetDescriptor())
 233   2                  switch(SETUPDAT[3])         
 234   2                  {
 235   3                     case GD_DEVICE:            // Device
 236   3                        SUDPTRH = MSB(pDeviceDscr);
 237   3                        SUDPTRL = LSB(pDeviceDscr);
 238   3                        break;
 239   3                     case GD_DEVICE_QUALIFIER:            // Device Qualifier
 240   3                                        // only retuen a device qualifier if this is a high speed
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 5   

 241   3                                        // capable chip.
 242   3                                        if (HighSpeedCapable())
 243   3                                        {
 244   4                                SUDPTRH = MSB(pDeviceQualDscr);
 245   4                                SUDPTRL = LSB(pDeviceQualDscr);
 246   4                                        }
 247   3                                        else
 248   3                                        {
 249   4                                                EZUSB_STALL_EP0();
 250   4                                        }
 251   3                                        break;
 252   3                     case GD_CONFIGURATION:         // Configuration
 253   3                        SUDPTRH = MSB(pConfigDscr);
 254   3                        SUDPTRL = LSB(pConfigDscr);
 255   3                        break;
 256   3                     case GD_OTHER_SPEED_CONFIGURATION:  // Other Speed Configuration
 257   3                        SUDPTRH = MSB(pOtherConfigDscr);
 258   3                        SUDPTRL = LSB(pOtherConfigDscr);
 259   3                        break;
 260   3                     case GD_STRING:            // String
 261   3                        if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
 262   3                        {
 263   4                           SUDPTRH = MSB(dscr_ptr);
 264   4                           SUDPTRL = LSB(dscr_ptr);
 265   4                        }
 266   3                        else 
 267   3                           EZUSB_STALL_EP0();   // Stall End Point 0
 268   3                        break;
 269   3                     default:            // Invalid request
 270   3                        EZUSB_STALL_EP0();      // Stall End Point 0
 271   3                  }
 272   2               break;
 273   2            case SC_GET_INTERFACE:                  // *** Get Interface
 274   2               DR_GetInterface();
 275   2               break;
 276   2            case SC_SET_INTERFACE:                  // *** Set Interface
 277   2               DR_SetInterface();
 278   2               break;
 279   2            case SC_SET_CONFIGURATION:               // *** Set Configuration
 280   2               DR_SetConfiguration();
 281   2               break;
 282   2            case SC_GET_CONFIGURATION:               // *** Get Configuration
 283   2               DR_GetConfiguration();
 284   2               break;
 285   2            case SC_GET_STATUS:                  // *** Get Status
 286   2               if(DR_GetStatus())
 287   2                  switch(SETUPDAT[0])
 288   2                  {
 289   3                     case GS_DEVICE:            // Device
 290   3                        EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
 291   3                        EP0BUF[1] = 0;
 292   3                        EP0BCH = 0;
 293   3                        EP0BCL = 2;
 294   3                        break;
 295   3                     case GS_INTERFACE:         // Interface
 296   3                        EP0BUF[0] = 0;
 297   3                        EP0BUF[1] = 0;
 298   3                        EP0BCH = 0;
 299   3                        EP0BCL = 2;
 300   3                        break;
 301   3                     case GS_ENDPOINT:         // End Point
 302   3                        EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL;
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 6   

 303   3                        EP0BUF[1] = 0;
 304   3                        EP0BCH = 0;
 305   3                        EP0BCL = 2;
 306   3                        break;
 307   3                     default:            // Invalid Command
 308   3                        EZUSB_STALL_EP0();      // Stall End Point 0
 309   3                  }
 310   2               break;
 311   2            case SC_CLEAR_FEATURE:                  // *** Clear Feature
 312   2               if(DR_ClearFeature())
 313   2                  switch(SETUPDAT[0])
 314   2                  {
 315   3                     case FT_DEVICE:            // Device
 316   3                        if(SETUPDAT[2] == 1)
 317   3                           Rwuen = FALSE;       // Disable Remote Wakeup
 318   3                        else
 319   3                           EZUSB_STALL_EP0();   // Stall End Point 0
 320   3                        break;
 321   3                     case FT_ENDPOINT:         // End Point
 322   3                        if(SETUPDAT[2] == 0)
 323   3                        {
 324   4                           *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL;
 325   4                           EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
 326   4                        }
 327   3                        else
 328   3                           EZUSB_STALL_EP0();   // Stall End Point 0
 329   3                        break;
 330   3                  }
 331   2               break;
 332   2            case SC_SET_FEATURE:                  // *** Set Feature
 333   2               if(DR_SetFeature())
 334   2                  switch(SETUPDAT[0])
 335   2                  {
 336   3                     case FT_DEVICE:            // Device
 337   3                        if(SETUPDAT[2] == 1)
 338   3                           Rwuen = TRUE;      // Enable Remote Wakeup
 339   3                        else if(SETUPDAT[2] == 2)
 340   3                           // Set Feature Test Mode.  The core handles this request.  However, it is
 341   3                           // necessary for the firmware to complete the handshake phase of the
 342   3                           // control transfer before the chip will enter test mode.  It is also
 343   3                           // necessary for FX2 to be physically disconnected (D+ and D-)
 344   3                           // from the host before it will enter test mode.
 345   3                           break;
 346   3                        else
 347   3                           EZUSB_STALL_EP0();   // Stall End Point 0
 348   3                        break;
 349   3                     case FT_ENDPOINT:         // End Point
 350   3                        *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL;
 351   3                        break;
 352   3                     default:
 353   3                        EZUSB_STALL_EP0();      // Stall End Point 0
 354   3                  }
 355   2               break;
 356   2            default:                     // *** Invalid Command
 357   2               if(DR_VendorCmnd())
 358   2                  EZUSB_STALL_EP0();            // Stall End Point 0
 359   2         }
 360   1      
 361   1         // Acknowledge handshake phase of device request
 362   1         EP0CS |= bmHSNAK;
 363   1      }
 364          
C51 COMPILER V7.07   FW                                                                    04/28/2005 15:22:07 PAGE 7   

 365          // Wake-up interrupt handler
 366          void resume_isr(void) interrupt WKUP_VECT
 367          {
 368   1         EZUSB_CLEAR_RSMIRQ();
 369   1      }
 370          
 371          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    941    ----
   CONSTANT SIZE    =     10    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     14      16
   IDATA SIZE       =   ----    ----
   BIT SIZE         =      4    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)
