C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 1 C51 COMPILER V8.09, COMPILATION OF MODULE FX2FRAMEWORK OBJECT MODULE PLACED IN .\Debug\FX2Framework.obj COMPILER INVOKED BY: C:\Program Files\Keil\C51\BIN\C51.EXE FX2Framework.c ROM(COMPACT) OPTIMIZE(6,SPEED) DEBUG OBJECTEXT -END OBJECT(.\Debug\FX2Framework.obj) line level source 1 //------------------------------------------------------------------------------ 2 // Cypress provided (C) 2005 framework for the FX2LP USB microcontroller. 3 // All rights reserved. 4 // Update from Piero Giubilato to fit the PARROT project. 5 //------------------------------------------------------------------------------ 6 7 //______________________________________________________________________________ 8 // {Trace} 9 // [File name] "FX2Framework.c" 10 // [Author] "Cypress" 11 // [Modified by] "Piero Giubilato" 12 // [Last revision] "02 Nov 2007" 13 // [Language] "C Standard" 14 // [Compiler] "Keil uVision 3.53" 15 // [Member of] "FX2 Firmware" 16 // [Project] "PARROT" 17 // [Description] "This file is the main framework provided by Cypress in order" 18 // "to build a USB-compliant firmware. Basically, it starts the device, set it up" 19 // "and then handles all the conditions the device can undergo (stand-by, ...)." 20 // "In the PARROT project it is used just to prime the device and then to put it" 21 // "into Slave FIFO Mode through the call to the TD_Init function in periph.c" 22 // [Key documentation] "Cypress EZ-USB Technical Reference Manual" 23 // {Trace} 24 //______________________________________________________________________________ 25 26 //______________________________________________________________________________ 27 // {Description} 28 // 29 // 30 // 31 // 32 // 33 // 34 // {Description} 35 //______________________________________________________________________________ 36 37 38 39 //------------------------------------------------------------------------------ 40 // Set resl allocation for FX2 registers (see FX2regs.h) 41 //------------------------------------------------------------------------------ 42 #define ALLOCATE_EXTERN 43 44 //------------------------------------------------------------------------------ 45 // Copyright 2003, Cypress Semiconductor Corporation 46 //------------------------------------------------------------------------------ 47 #include "fx2.h" 48 #include "fx2regs.h" 49 #include "syncdly.h" // SYNCDELAY macro 50 51 //------------------------------------------------------------------------------ 52 // Constants 53 //------------------------------------------------------------------------------ 54 #define DELAY_COUNT 0x9248*8L // Delay for 8 sec at 24Mhz, 4 sec at 48 C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 2 55 #define _IFREQ 48000 // IFCLK constant for Synchronization Delay 56 #define _CFREQ 48000 // CLKOUT constant for Synchronization Delay 57 58 //------------------------------------------------------------------------------ 59 // Random Macros 60 //------------------------------------------------------------------------------ 61 #define min(a,b) (((a)<(b))?(a):(b)) 62 #define max(a,b) (((a)>(b))?(a):(b)) 63 64 //------------------------------------------------------------------------------ 65 // Global Variables 66 //------------------------------------------------------------------------------ 67 volatile BOOL GotSUD; 68 BOOL Rwuen; 69 BOOL Selfpwr; 70 volatile BOOL Sleep; // Sleep mode enable flag 71 72 WORD pDeviceDscr; // Pointer to Device Descriptor; Descriptors may be moved 73 WORD pDeviceQualDscr; 74 WORD pHighSpeedConfigDscr; 75 WORD pFullSpeedConfigDscr; 76 WORD pConfigDscr; 77 WORD pOtherConfigDscr; 78 WORD pStringDscr; 79 80 //------------------------------------------------------------------------------ 81 // Prototypes 82 //------------------------------------------------------------------------------ 83 void SetupCommand(void); 84 void TD_Init(void); 85 void TD_Poll(void); 86 BOOL TD_Suspend(void); 87 BOOL TD_Resume(void); 88 89 BOOL DR_GetDescriptor(void); 90 BOOL DR_SetConfiguration(void); 91 BOOL DR_GetConfiguration(void); 92 BOOL DR_SetInterface(void); 93 BOOL DR_GetInterface(void); 94 BOOL DR_GetStatus(void); 95 BOOL DR_ClearFeature(void); 96 BOOL DR_SetFeature(void); 97 BOOL DR_VendorCmnd(void); 98 99 // this table is used by the epcs macro 100 const char code EPCS_Offset_Lookup_Table[] = 101 { 102 0, // EP1OUT 103 1, // EP1IN 104 2, // EP2OUT 105 2, // EP2IN 106 3, // EP4OUT 107 3, // EP4IN 108 4, // EP6OUT 109 4, // EP6IN 110 5, // EP8OUT 111 5, // EP8IN 112 }; 113 114 // macro for generating the address of an endpoint's control and status register (EPnCS) 115 #define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1) 116 C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 3 117 //----------------------------------------------------------------------------- 118 // Code 119 //----------------------------------------------------------------------------- 120 121 // Task dispatcher 122 void main(void) 123 { 124 1 DWORD i; 125 1 WORD offset; 126 1 DWORD DevDescrLen; 127 1 DWORD j=0; 128 1 WORD IntDescrAddr; 129 1 WORD ExtDescrAddr; 130 1 131 1 // Initialize Global States 132 1 Sleep = FALSE; // Disable sleep mode 133 1 Rwuen = FALSE; // Disable remote wakeup 134 1 Selfpwr = FALSE; // Disable self powered 135 1 GotSUD = FALSE; // Clear "Got setup data" flag 136 1 137 1 // Initialize user device 138 1 TD_Init(); 139 1 140 1 // The following section of code is used to relocate the descriptor table. 141 1 // The frameworks uses SUDPTRH and SUDPTRL to automate the SETUP requests 142 1 // for descriptors. These registers only work with memory locations 143 1 // in the EZ-USB internal RAM. Therefore, if the descriptors are located 144 1 // in external RAM, they must be copied to in internal RAM. 145 1 // The descriptor table is relocated by the frameworks ONLY if it is found 146 1 // to be located in external memory. 147 1 pDeviceDscr = (WORD)&DeviceDscr; 148 1 pDeviceQualDscr = (WORD)&DeviceQualDscr; 149 1 pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr; 150 1 pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr; 151 1 pStringDscr = (WORD)&StringDscr; 152 1 153 1 // Is the descriptor table in external RAM (> 16Kbytes)? If yes, 154 1 // then relocate. 155 1 // Note that this code only checks if the descriptors START in 156 1 // external RAM. It will not work if the descriptor table spans 157 1 // internal and external RAM. 158 1 if ((WORD)&DeviceDscr & 0xC000) 159 1 { 160 2 // first, relocate the descriptors 161 2 IntDescrAddr = INTERNAL_DSCR_ADDR; 162 2 ExtDescrAddr = (WORD)&DeviceDscr; 163 2 DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2; 164 2 for (i = 0; i < DevDescrLen; i++) 165 2 *((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i); 166 2 167 2 // update all of the descriptor pointers 168 2 pDeviceDscr = IntDescrAddr; 169 2 offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR; 170 2 pDeviceQualDscr -= offset; 171 2 pConfigDscr -= offset; 172 2 pOtherConfigDscr -= offset; 173 2 pHighSpeedConfigDscr -= offset; 174 2 pFullSpeedConfigDscr -= offset; 175 2 pStringDscr -= offset; 176 2 } 177 1 178 1 EZUSB_IRQ_ENABLE(); // Enable USB interrupt (INT2) C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 4 179 1 EZUSB_ENABLE_RSMIRQ(); // Wake-up interrupt 180 1 181 1 INTSETUP |= (bmAV2EN | bmAV4EN); // Enable INT 2 & 4 autovectoring 182 1 183 1 USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; // Enable selected interrupts 184 1 EA = 1; // Enable 8051 interrupts 185 1 186 1 #ifndef NO_RENUM 187 1 // Renumerate if necessary. Do this by checking the renum bit. If it 188 1 // is already set, there is no need to renumerate. The renum bit will 189 1 // already be set if this firmware was loaded from an eeprom. 190 1 if(!(USBCS & bmRENUM)) 191 1 { 192 2 EZUSB_Discon(TRUE); // renumerate 193 2 } 194 1 #endif 195 1 196 1 // unconditionally re-connect. If we loaded from eeprom we are 197 1 // disconnected and need to connect. If we just renumerated this 198 1 // is not necessary but doesn't hurt anything 199 1 USBCS &=~bmDISCON; 200 1 201 1 CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch 202 1 203 1 // clear the Sleep flag. 204 1 Sleep = FALSE; 205 1 206 1 // Task Dispatcher 207 1 while(TRUE) // Main Loop 208 1 { 209 2 // Poll User Device 210 2 TD_Poll(); 211 2 212 2 // Check for pending SETUP 213 2 if(GotSUD) 214 2 { 215 3 SetupCommand(); // Implement setup command 216 3 GotSUD = FALSE; // Clear SETUP flag 217 3 } 218 2 219 2 // check for and handle suspend. 220 2 // NOTE: Idle mode stops the processor clock. There are only two 221 2 // ways out of idle mode, the WAKEUP pin, and detection of the USB 222 2 // resume state on the USB bus. The timers will stop and the 223 2 // processor will not wake up on any other interrupts. 224 2 if (Sleep) 225 2 { 226 3 if(TD_Suspend()) 227 3 { 228 4 Sleep = FALSE; // Clear the "go to sleep" flag. Do it here to prevent any race condition -between wakeup and the next sleep. 229 4 do 230 4 { 231 5 EZUSB_Susp(); // Place processor in idle mode. 232 5 } 233 4 while(!Rwuen && EZUSB_EXTWAKEUP()); 234 4 // above. Must continue to go back into suspend if the host has disabled remote wakeup 235 4 // *and* the wakeup was caused by the external wakeup pin. 236 4 237 4 // 8051 activity will resume here due to USB bus or Wakeup# pin activity. 238 4 EZUSB_Resume(); // If source is the Wakeup# pin, signal the host to Resume. 239 4 TD_Resume(); C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 5 240 4 } 241 3 } 242 2 243 2 } 244 1 } 245 246 BOOL HighSpeedCapable() 247 { 248 1 // this function determines if the chip is high-speed capable. 249 1 // FX2 and FX2LP are high-speed capable. FX1 is not - it does 250 1 // not have a high-speed transceiver. 251 1 252 1 /* 253 1 if (GPCR2 & bmFULLSPEEDONLY) 254 1 return FALSE; 255 1 else */ 256 1 return TRUE; 257 1 } 258 259 // Device request parser 260 void SetupCommand(void) 261 { 262 1 void *dscr_ptr; 263 1 264 1 switch(SETUPDAT[1]) 265 1 { 266 2 case SC_GET_DESCRIPTOR: // *** Get Descriptor 267 2 if(DR_GetDescriptor()) 268 2 switch(SETUPDAT[3]) 269 2 { 270 3 case GD_DEVICE: // Device 271 3 SUDPTRH = MSB(pDeviceDscr); 272 3 SUDPTRL = LSB(pDeviceDscr); 273 3 break; 274 3 case GD_DEVICE_QUALIFIER: // Device Qualifier 275 3 // only retuen a device qualifier if this is a high speed 276 3 // capable chip. 277 3 if (HighSpeedCapable()) 278 3 { 279 4 SUDPTRH = MSB(pDeviceQualDscr); 280 4 SUDPTRL = LSB(pDeviceQualDscr); 281 4 } 282 3 else 283 3 { 284 4 EZUSB_STALL_EP0(); 285 4 } 286 3 break; 287 3 case GD_CONFIGURATION: // Configuration 288 3 SUDPTRH = MSB(pConfigDscr); 289 3 SUDPTRL = LSB(pConfigDscr); 290 3 break; 291 3 case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration 292 3 SUDPTRH = MSB(pOtherConfigDscr); 293 3 SUDPTRL = LSB(pOtherConfigDscr); 294 3 break; 295 3 case GD_STRING: // String 296 3 if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2])) 297 3 { 298 4 SUDPTRH = MSB(dscr_ptr); 299 4 SUDPTRL = LSB(dscr_ptr); 300 4 } 301 3 else C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 6 302 3 EZUSB_STALL_EP0(); // Stall End Point 0 303 3 break; 304 3 default: // Invalid request 305 3 EZUSB_STALL_EP0(); // Stall End Point 0 306 3 } 307 2 break; 308 2 case SC_GET_INTERFACE: // *** Get Interface 309 2 DR_GetInterface(); 310 2 break; 311 2 case SC_SET_INTERFACE: // *** Set Interface 312 2 DR_SetInterface(); 313 2 break; 314 2 case SC_SET_CONFIGURATION: // *** Set Configuration 315 2 DR_SetConfiguration(); 316 2 break; 317 2 case SC_GET_CONFIGURATION: // *** Get Configuration 318 2 DR_GetConfiguration(); 319 2 break; 320 2 case SC_GET_STATUS: // *** Get Status 321 2 if(DR_GetStatus()) 322 2 switch(SETUPDAT[0]) 323 2 { 324 3 case GS_DEVICE: // Device 325 3 EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr; 326 3 EP0BUF[1] = 0; 327 3 EP0BCH = 0; 328 3 EP0BCL = 2; 329 3 break; 330 3 case GS_INTERFACE: // Interface 331 3 EP0BUF[0] = 0; 332 3 EP0BUF[1] = 0; 333 3 EP0BCH = 0; 334 3 EP0BCL = 2; 335 3 break; 336 3 case GS_ENDPOINT: // End Point 337 3 EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL; 338 3 EP0BUF[1] = 0; 339 3 EP0BCH = 0; 340 3 EP0BCL = 2; 341 3 break; 342 3 default: // Invalid Command 343 3 EZUSB_STALL_EP0(); // Stall End Point 0 344 3 } 345 2 break; 346 2 case SC_CLEAR_FEATURE: // *** Clear Feature 347 2 if(DR_ClearFeature()) 348 2 switch(SETUPDAT[0]) 349 2 { 350 3 case FT_DEVICE: // Device 351 3 if(SETUPDAT[2] == 1) 352 3 Rwuen = FALSE; // Disable Remote Wakeup 353 3 else 354 3 EZUSB_STALL_EP0(); // Stall End Point 0 355 3 break; 356 3 case FT_ENDPOINT: // End Point 357 3 if(SETUPDAT[2] == 0) 358 3 { 359 4 *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL; 360 4 EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] ); 361 4 } 362 3 else 363 3 EZUSB_STALL_EP0(); // Stall End Point 0 C51 COMPILER V8.09 FX2FRAMEWORK 12/28/2007 10:51:03 PAGE 7 364 3 break; 365 3 } 366 2 break; 367 2 case SC_SET_FEATURE: // *** Set Feature 368 2 if(DR_SetFeature()) 369 2 switch(SETUPDAT[0]) 370 2 { 371 3 case FT_DEVICE: // Device 372 3 if(SETUPDAT[2] == 1) 373 3 Rwuen = TRUE; // Enable Remote Wakeup 374 3 else if(SETUPDAT[2] == 2) 375 3 // Set Feature Test Mode. The core handles this request. However, it is 376 3 // necessary for the firmware to complete the handshake phase of the 377 3 // control transfer before the chip will enter test mode. It is also 378 3 // necessary for FX2 to be physically disconnected (D+ and D-) 379 3 // from the host before it will enter test mode. 380 3 break; 381 3 else 382 3 EZUSB_STALL_EP0(); // Stall End Point 0 383 3 break; 384 3 case FT_ENDPOINT: // End Point 385 3 *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL; 386 3 break; 387 3 default: 388 3 EZUSB_STALL_EP0(); // Stall End Point 0 389 3 } 390 2 break; 391 2 default: // *** Invalid Command 392 2 if(DR_VendorCmnd()) 393 2 EZUSB_STALL_EP0(); // Stall End Point 0 394 2 } 395 1 396 1 // Acknowledge handshake phase of device request 397 1 EP0CS |= bmHSNAK; 398 1 } 399 400 // Wake-up interrupt handler 401 void resume_isr(void) interrupt WKUP_VECT 402 { 403 1 EZUSB_CLEAR_RSMIRQ(); 404 1 } 405 406 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 1004 ---- 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)