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

📄 fw.c

📁 Cy68013的应用——USB2.0接口转IDE、CF卡接口
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//   File:      fw.c
//   Contents:   Firmware frameworks task dispatcher and device request parser
//            source.
//
// indent 3.  NO TABS!
//
//   Copyright (c) 2001 Cypress Semiconductor
//
// $Workfile: fw.c $
// $Date: 7/25/02 12:40p $
// $Revision: 31 $
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "gpif.h"
#include "atapi.h"
#include "custom.h"
#include "globals.h"

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define DELAY_COUNT   0x9248*8L      // Delay for 8 sec at 24Mhz, 4 sec at 48
// USB constants
// Class specific setup commands
#define SC_BOMS_RESET           (0x21)      // Hard/soft depends on wValue field 0 = hard

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


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

// Task dispatcher

void main(void)
{
   BYTE j;

   // if we are hung up in a GPIF transfer, abort it.  How could this happen?  If
   // we ended up here after a USB Reset or a MSC Reset, it is possible that the
   // GPIF is hung waiting for a transfer that will never complete.
   abortGPIF(); // TPM: Unconditionally abort

   TD_Init();      

   EZUSB_IRQ_ENABLE();            // Enable USB interrupt (INT2)
   EZUSB_ENABLE_RSMIRQ();            // Wake-up interrupt

   INTSETUP |= (bmAV2EN);     // Enable INT 2 autovectoring

   USBIE |= bmSUDAV | bmSUSP | bmURES | bmHSGRANT;   // Enable selected interrupts

   Sleep = 0;

   noFlashMedia = 1;

   // if there is a CF device, increment our deviceCount so that any detected
   // ATA/ATAPI devices get assigned to LUN1
   #if COMPACT_FLASH
      deviceCount++;
   #endif

   // Allow customization of startup.  This macro contains an IF statement
   // DO NOT PUT A SEMICOLON after this command.
   CUSTOM_SKIP_ID_DEVICE_IF()
      if (ATA_ENABLED)
      {
         resetATAPIDevice();

         // keep searching for ATA/ATAPI device until we find at least one
         while (!(LunBits[0] || LunBits[1]))
         {
            for (j=deviceCount;j<MAX_LUN;j++)
            {
               // Clearing ActiveLunBits clears the bMasterSlaveBit (i.e. we will search for the master the next time
               // through this loop)
               ActiveLunBits = 0;

               bMasterSlave = j;    
               detectSCSIvsATA();
               if (bDevicePresent)
               {
                  LunBits[deviceCount] = ActiveLunBits;
                  deviceCount++;
               }
            }
         }

         for (j=0;j<deviceCount;j++)
         {
            ActiveLunBits = LunBits[j];
            if (bDevicePresent)
            {
               ATAPIIdDevice();
               mymemmove((BYTE *)&DeviceConfigData[j],(BYTE *)&ActiveLunConfigData, sizeof(DEVICE_CONFIG_DATA));
               LunBits[j] = ActiveLunBits;
            }
         }


      }

   #if COMPACT_FLASH
      ActiveLunBits = 0;
      bDevicePresent = 1;
      bCompactFlash = 1;
      bMasterSlave = 0;             // CF is always the master
      LunBits[0] = ActiveLunBits;
   #endif

   // wait to enable interrupts until we have completed device identification.  why?
   // because there is certain information that we won't have until after we have
   // detected the drives.  Specifically, we may be getting a serial number from
   // the drive and we also need to detect how many drives there are so we can respond
   // to the GET MAX LUN request correctly.
   EA = 1;                  // Enable 8051 interrupts
   TR0 = 1;                 // Make sure that the timer ISR runs at once.  This will take care of the ATA_ENABLE line
      
   // CompactFlash hasn't loaded it's waves yet.  Force gear shift on first msg.
   currentLunNum = 0xff;

   // 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 or if we
   // have already been through this code once and we are here again
   // because of a USB Reset.
   if(!(USBCS & bmRENUM))
   {
       EZUSB_Discon(TRUE);   // renumerate -- Note this is a special version of DISCON for us.  It does NOT reconnect
   }

   // This macro allows customization before we connect to the USB bus.
   CUSTOM_WAIT_BEFORE_CONNECT()

#if !VBUS_DETECT
   // 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;
#endif
   
   CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)

   // complete the handshake phase of any pending SETUP transfer.
   // The only time this should happen is after a MSC Reset.  We want
   // to go through all of the EP init code before handshaking the status
   // phase of the MSC Reset.
   EP0CS |= bmHSNAK;

   // Task Dispatcher
   while(TRUE)                     // Main Loop
   {
#if BUS_POWERED
      if (Sleep)
      {
         Sleep = 0;

         // If we have already touched IFCONFIG, need to drive the ports to a known value
         // This helps suspend with CompactFlash.  We must check before touching IFCONFIG
         // because we briefly sleep on startup and we don't want to turn the GPIF on until
         // we are configured by the host.
         if (IFCONFIG & 0x3)
            { 
            IFCONFIG = IFCONFIG_DEFAULT & ~3;   // Turn off GPIF control of ports B and D.
   
            IOD = IOB = 0;
            OEB = OED = 0xff;

            EZUSB_Susp();         // Place processor in idle mode.

            OEB = OED = 0;
            IFCONFIG = IFCONFIG_DEFAULT;
            }
         else
            EZUSB_Susp();         // Place processor in idle mode.
      }
#endif
      TD_Poll();
   }
}

// Standard requests are 
#define STANDARD(x)  (x | (SETUP_STANDARD_REQUEST<<8))  
#define CLASS(x) (x | (SETUP_CLASS_REQUEST << 8))

// Device request parser
void SetupCommand(void)
{
   if ((SETUPDAT[0] & SETUP_MASK) == SETUP_STANDARD_REQUEST)
      {
      switch(SETUPDAT[1])
         {
         case SC_GET_DESCRIPTOR:                      // *** Get Descriptor
            switch(SETUPDAT[3])         
               {
                  case GD_DEVICE:                     // Device
                     SUDPTRH = MSB(pDeviceDscr);
                     SUDPTRL = LSB(pDeviceDscr);
                     break;
                  case GD_DEVICE_QUALIFIER:            // Device Qualifier
                     // if high-speed is disabled, we are supposed to STALL this request
                     if (!CT1)
                     {
                        // high-speed is enabled, return the device qualifier
                        SUDPTRH = MSB(pDeviceQualDscr);
                        SUDPTRL = LSB(pDeviceQualDscr);
                     }
                     else
                     {
                        // high-speed is disabled, STALL this request
                        EZUSB_STALL_EP0();
                     }
                     break;
                  case GD_CONFIGURATION:              // Configuration
                     SUDPTRH = MSB(pConfigDscr);
                     SUDPTRL = LSB(pConfigDscr);
                     break;
                  case GD_OTHER_SPEED_CONFIGURATION:  // Other Speed Configuration
                     // fx2bug - need to support multi other configs
                     SUDPTRH = MSB(pOtherConfigDscr);
                     SUDPTRL = LSB(pOtherConfigDscr);
                     break;
                  case GD_STRING:            // String
                     {
                     void   *dscr_ptr;
                     dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]);
                     SUDPTRH = MSB(dscr_ptr);
                     SUDPTRL = LSB(dscr_ptr);
                     break;
                     }
                  #if BUS_POWERED
                  case GD_HID:					// Get-Descriptor: HID
                     SUDPTRH = MSB(pHIDDscr);
                     SUDPTRL = LSB(pHIDDscr);
                     break;

                  case GD_REPORT:					// Get-Descriptor: Report
                     {
                     /*
                     Note: A HID report does not have a length field which the SIE can read to determine how many
                     bytes to send using the Setup Data Pointer. Therefore we need to 'manually' send the data.
                     We have limited our report size to less than 64 bytes.
                     */
                     BYTE j;

                     AUTOPTR1H = MSB(pHIDReportDscr);
                     AUTOPTR1L = LSB(pHIDReportDscr);
                     for(j=0;j<64;j++)
                        EP0BUF[j]=XAUTODAT1;
                     EP0BCH = 0;
                     EP0BCL = (WORD)&HIDReportDscrEndOffset-(WORD)&HIDReportDscrOffset;          // arm the IN transfer
                     break;
                     }
                  #endif

⌨️ 快捷键说明

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