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

📄 atareset.c

📁 cy68013a USB2.0 highspeed mass storage source code
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//  Copyright (c) 1999-2001 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
//
// This file contains the device initialization code.  
//
// $Workfile: atareset.c $
// $Date: 6/30/05 10:48a $
// $Revision: 6 $
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "gpif.h"
#include "globals.h"

// Cannot define these in "globals" because then they will end up in halfKbuffer
MX2_CONFIG_DATA xdata mx2_config_data;

void detectSCSIvsATA();

///////////////////////////////////////////////////////////////////////////////////////////
//
// ATAInit() -- Drive reset and discovery
//
// Inputs:
//    DeviceCount -- Determines if drive discovery variables must be initialized
//    bFirstTime -- Determines if drive discovery is necessary
//    
// Outputs:
//    deviceCount -- Set from 0x8x to 1 or 2 when the drive count is known.
//    LunBits[] -- set to reflect drive parameters
//    bFirstTime -- cleared when this routine is completed
//
///////////////////////////////////////////////////////////////////////////////////////////
void ATAInit()
{
   BYTE j;

   if (bFirstTime || deviceCount > 0x7f)
      {
      // Locally initialize globals used by ATAInit.
      deviceCount = 0x80;
      LunBits[0] = LunBits[1] = ActiveLunBits = 0;    // zeroes out bCompactFlash, bScsi, bExtAddrSupport

      // if there is a CF device, increment our deviceCount so that any detected
      // ATA/ATAPI devices get assigned to LUN1
      if (bDRVPWRVLD_ENABLE)
         deviceCount = 0x81;
      }

   if (ATA_ENABLED)
      {
      resetATAPIDevice();

      // keep searching for ATA/ATAPI device until we find at least one
      if (deviceCount > 0x7f)    // syk
         {
         while (!(LunBits[0] || LunBits[1]))
            {
            for (j=(deviceCount & 3);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&3] = ActiveLunBits;
                  deviceCount++;
                  }
               }
            if (!(LunBits[0] || LunBits[1]))
               if (bDRVPWRVLD_ENABLE)
                  {
                  // Cycle power on the CF if it seems to be interfering
                  IOEShadow |= nPWR500;    // Turn off the power
                  IOE = IOEShadow;
                  EZUSB_Delay(10);
                  IOEShadow &= ~nPWR500;   // Turn on the power
                  IOE = IOEShadow;
                  EZUSB_Delay(10);
                  }
            }
         for (currentLunNum=0;currentLunNum<(deviceCount&3);currentLunNum++)
            {
               ActiveLunBits = LunBits[currentLunNum];
               if (bDevicePresent)
               {
                  FIFORESET = 0x06;            // Make sure that the IN buffer is empty
                  ATAPIIdDevice();
                  mymemmove((BYTE *)&DeviceConfigData[currentLunNum],(BYTE *)&ActiveLunConfigData, sizeof(DEVICE_CONFIG_DATA));
                  LunBits[currentLunNum] = ActiveLunBits;
               }
            }
         }
      }

   if (bDRVPWRVLD_ENABLE)
      {
      ActiveLunBits = 0;
      bDevicePresent = 1;
      bCompactFlash = 1;
      bMasterSlave = 0;             // CF is always the master
      LunBits[0] = ActiveLunBits;
      }

   for (currentLunNum = 0; currentLunNum < (deviceCount & 3); currentLunNum++)
      {
      ActiveLunBits = LunBits[currentLunNum];
      mymemmove((BYTE *)&ActiveLunConfigData,(BYTE *)&DeviceConfigData[currentLunNum], sizeof(DEVICE_CONFIG_DATA));
      if (!bCompactFlash)        // Compact Flash is configured when it's detected, not at startup.
         initDriveAfterReset();  // Take info collected into activeLunConfigData and configure the drive.
      }
   deviceCount &= 0x3;     // Clear flag bits
   bFirstTime = 0;

   // CompactFlash hasn't loaded it's waves yet.  Force gear shift on first msg.
   currentLunNum = 0xff;
}

// PIO3 waves are PIO waves but with 6 instead of 4 in the wave 0 and wave 1 lenbr field
void resetATAPIDevice()
{

   sensePtr = senseDeviceReset;

   if (bFirstTime)
      EZUSB_Delay(DELAY_AFTER_POWERUP);            // Wait for stable power -- Sony CDU4811 and Maxtor 34098 (40G) are good tests for this
   

   /////////////////////////////////////////////////////////////////////////////////////
   // Perform hardware reset ONCE on reset, then obey the skip pin reset flag
   if ((bFirstTime) || !(SKIP_PIN_RESET))
   {
      hardwareReset();
      EZUSB_Delay(90);            // Mitsumi CR-4808TE(CYSD007) is a good test for this number.
      // give devices a chance to recover after ATA reset
   }
    
   /////////////////////////////////////////////////////////////////////////////////////
   // Perform software reset and retest for SCSI vs ATA
   else if (SRST_ENABLE)
   {
      writePIO8(ATAPI_CONTROL_REG, ATAPI_CONTROL_REG_SOFT_RESET);
      EZUSB_Delay(50);            
      writePIO8(ATAPI_CONTROL_REG, 0);
   }
   if (mx2_config_data.delayAfterReset)
      {
      EZUSB_Delay(mx2_config_data.delayAfterReset * 20);
      }
   else
      {
      EZUSB_Delay(DELAY_AFTER_RESET);
      }
}


// Uses these globals:
//    bMasterSlave
// Stuffs these globals:
//    bScsi -- Set to 1 if EB14 is detected in the LBA registers
//    bDevicePresent -- Set to 1 if device is found, 0 if not found
void detectSCSIvsATA()
{
   EZUSB_Delay(8);            // Wait 5 ms to be polite
   writePIO8(ATAPI_CONTROL_REG, 0);       // Make sure that SRST is not set
   writeATA_DRIVESEL_REG();

   // wait for the busy bit to clear.  Even if there is no device, the busy bit will
   // go to zero because of the pulldown on D7
   waitForBusyBit();
   writeATA_DRIVESEL_REG();

   writePIO8(ATAPI_NULL_REG, ~0xE0);      // Make sure that the bus is NOT still floating at 0xa0

   // Read back the Drive Select register.  If it contains what we wrote to it, then
   // there may be a device here.  Otherwise return.
   if (!((readPIO8(ATA_DRIVESEL_REG) & 0xF0) == (0xe0 | ((BYTE) bMasterSlave << 4))))
         return;

   // Check for passing self-test result
   if (!readPIO8(ATAPI_ERROR_REG))
      return;

   // Check for special SCSI byte count value.  EB14 indicates an ATAPI device.
   // If we read EB14, we know we have a real scsi device and we can quit
   if (readPIO8(ATAPI_BYTE_COUNT_MSB) == 0xeb && readPIO8(ATAPI_BYTE_COUNT_LSB) == 0x14)
   {
      bScsi = 1;
   }
   
   // We now have identified a device that's responding to our commands.  If we have 
   // selected the slave, it could be a master responding for the slave device.
   // ATA devices in this case can be detected by seeing a 0 in the status register.
   if (!bMasterSlave)   // Master devices are done here.
   {
      bDevicePresent = 1;
      return;
   }

//   if (bScsi)
      {
      SendDeviceIdentifyCommand(0);
      if ((readATAPI_ALT_STATUS_REG() & (ATAPI_STATUS_DRQ_BIT | ATAPI_STATUS_ERROR_BIT)) == ATAPI_STATUS_DRQ_BIT)
         {
         bit oldEA = EA;
         EA = 0;

         FetchDeviceIdentifyIntoEp6();

         // Add a hack for Takaya CD1016 -- Needs recovery time after ID command
         EZUSB_Delay(1);

         bDevicePresent = 1;
         EA = oldEA;
         }
      }
//   else if (readATAPI_STATUS_REG())
//      bDevicePresent = 1;
}

void SendDeviceIdentifyCommand(bit waitForINTRQ)
{
//   do
      {
      writeATA_DRIVESEL_REG();
      waitForBusyBit();
      // Send Identify device command
      if (bScsi)
         writePIO8(ATAPI_COMMAND_REG, ATAPI_COMMAND_ID_DEVICE);
      else
         writePIO8(ATAPI_COMMAND_REG, IDE_COMMAND_ID_DEVICE);
      }

   // Wait for the register block to be non-busy.  Cannot depend on the DRDY bit since some
   // ATAPI devices will not set it on an A1 command.
   // SYK -- I'm not sure I believe this.  8.13.5 says that you must set DRDY on completion.

   // We use this command for two reasons.  One is to get the info, the other is as part of 
   // drive detection.  The drive detection algorithm takes care of command completion on its own.
   if (waitForINTRQ)
      WAIT_FOR_INTRQ();
   readATAPI_STATUS_REG();    // Clear the INTRQ
   waitForBusyBit();
}

// This function reads device IDENTIFY data from the drive and into EP6FIFOBUF.  You must first call 
// SendDeviceIdentifyCommand() to send the IDENTIFY command to the drive.  Interrrupts must be
// disabled around calls to this function to avoid simultaneous access to EP6FIFOBUF that could
// occur if a USB reset happens.
void FetchDeviceIdentifyIntoEp6()
{
   BYTE saveIt;
   // Read the data from the drive.  EP6FIFOBUF is used to store the data since we only
   // need it temporarily.
   saveIt = EP6FIFOCFG;
   EP6FIFOCFG = saveIt & ~bmAUTOIN;  // disable automode    
   readPIO16(ATA_SECTOR_SIZE);

⌨️ 快捷键说明

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