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

📄 atareset.c

📁 cy68013a USB2.0 highspeed mass storage source code
💻 C
📖 第 1 页 / 共 2 页
字号:
   while (!gpifIdle())    // wait for the read to complete before continuing
      ;
   OUTATAPI = ATAPI_IDLE_VALUE;   
   EP6FIFOCFG = saveIt;  // re-enable automode if it was set before.    
}

void ATAPIIdDevice()
{
   bit oldEA;

   SendDeviceIdentifyCommand(1);

// The code used to wait here until it saw the DRDY bit (0x40.  This bit is obsolete, but still supported by almost all devices.
// However, the TEAC CRN8245 drive will respond with ONLY the ATAPI_STATUS_DRQ_BIT set.
// This was kind of overkill anyway, since the INTRQ line has already indicated that the device is done with the command.
   while (!(readATAPI_STATUS_REG() & ATAPI_STATUS_DRQ_BIT))
      ;

   // We need to disable interrupts while using EP6FIFOBUF.  Here's why.  It is possible
   // (even probable) that we could get a USB reset while doing drive identification.
   // One of the things that occurs in the USB reset ISR is a reset of the EP6 FIFO.
   // It would be bad if that happened just as we were reading drive data into EP6FIFOBUF.
   // The following code segment will complete in a deterministic amount of time.
   oldEA = EA;
   EA = 0;
   
   FetchDeviceIdentifyIntoEp6();

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

   if (CSMIntrfcDscrOffset)
   {
      mymemmovexx(CSMSerial, EP6FIFOBUF+ATAPI_INQUIRY_SERIAL, IDE_ID_SERIAL_LEN);
   }

#if USE_ATAPI_DEVICE_SERIAL_NUMBER || USE_ATA_DEVICE_SERIAL_NUMBER
   if ((bScsi && USE_ATAPI_DEVICE_SERIAL_NUMBER) || (!bScsi && USE_ATA_DEVICE_SERIAL_NUMBER))
   {
      BYTE xdata *ptr = &halfKBuffer[(BYTE) &SerialNumberStringDscrOffset + 2];
      BYTE len = (halfKBuffer[(BYTE) &SerialNumberStringDscrOffset] >> 1) - 1;      // Structure len is bytes, we want unicode (words)
      BYTE i;

      for (i=0;i<len;i++, ptr += 2)
      {
         BYTE mychar = EP6FIFOBUF[i+ATAPI_INQUIRY_SERIAL];
#if NIBBLE_CONVERT_SERIAL_NUMBER
         {
            BYTE serialChar = (mychar >> 4) + '0';
            if (serialChar > '9')
               serialChar += 'A' - '9' - 1;
            *ptr = serialChar;
            ptr += 2; 
            i++;
            serialChar = (mychar & 0x0F) + '0';
            if (serialChar > '9')
               serialChar += 'A' - '9' - 1;
            *ptr = serialChar;
         }
#else
         {
         *ptr = mychar;
         }
#endif
      }
   }
#endif        
   // Check for large disk (48 bit) support.  ATA-6 spec below....
   // 6.2.1
   //    4) The contents of words (61:60) and (103:100) shall not be used to determine if 48-bit addressing is
   //       supported. IDENTIFY DEVICE bit 10 word 83 indicates support for 48-bit addressing.
   if (EP6FIFOBUF[IDENTIFY_48BIT_ADDRESSING+1] & (1<<2))
      {
      bExtAddrSupport = 1;
      // This is actually smaller than a loop of 4!!
      // Yes, this only supports 0x100 00 00 00 sectors, which is 220,000GB (industry GB, not true)
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[3] = EP6FIFOBUF[0+IDE_ID_TOTAL_48_BIT_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[2] = EP6FIFOBUF[1+IDE_ID_TOTAL_48_BIT_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[1] = EP6FIFOBUF[2+IDE_ID_TOTAL_48_BIT_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[0] = EP6FIFOBUF[3+IDE_ID_TOTAL_48_BIT_SECTORS_LSW];
      }
   else
      {
      bExtAddrSupport = 0;
      // This is actually smaller than a loop of 4!!
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[3] = EP6FIFOBUF[0+IDE_ID_TOTAL_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[2] = EP6FIFOBUF[1+IDE_ID_TOTAL_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[1] = EP6FIFOBUF[2+IDE_ID_TOTAL_SECTORS_LSW];
      ((BYTE *)&ActiveLunConfigData.driveCapacity)[0] = EP6FIFOBUF[3+IDE_ID_TOTAL_SECTORS_LSW];
      }

   ActiveLunConfigData.NumCylindersMSB = EP6FIFOBUF[IDENTIFY_NUM_CYLINDERS_MSB];
   ActiveLunConfigData.NumCylindersLSB = EP6FIFOBUF[IDENTIFY_NUM_CYLINDERS_LSB];
   ActiveLunConfigData.NumHeads = EP6FIFOBUF[IDENTIFY_NUM_HEADS];
   ActiveLunConfigData.NumSectPerTrack = EP6FIFOBUF[IDENTIFY_NUM_SECT_PER_TRACK];

   // check for PIO3 support (or greater).  PIO support is reported in the
   // IDENTIFY data from the drive.  AND the modes supported by the drive with
   // the PIO enables from the configuration eeprom to enable only selected modes.
   ActiveLunConfigData.MaxPIO = EP6FIFOBUF[IDENTIFY_ADVANCED_PIO] & PIO_MODES;
   ActiveLunConfigData.udmaMode = 0;

   // Check for UDMA support.  UDMA support is reported in the IDENTIFY data
   // from the drive.  AND the modes supported by the drive with the UDMA mode
   // enables from the configuration eeprom to enable only selected modes.
   if (EP6FIFOBUF[IDENTIFY_FIELD_VALIDITY] & bmBIT2)
   {
      BYTE supportedUdmaModes = 0;
      supportedUdmaModes = EP6FIFOBUF[IDENTIFY_UDMA_MODES] & UDMA_MODES;

      if (bScsi && !(ATAPI_UDMA_ENABLE))
         supportedUdmaModes = 0;

      if (!bScsi && !(ATA_UDMA_ENABLE))
         supportedUdmaModes = 0;

      if (bCompactFlash && !bCF_USES_UDMA)
         supportedUdmaModes = 0;

//      if (supportedUdmaModes & UDMA_MODE5)
//      {
//         ActiveLunConfigData.udmaMode = TRANSFER_MODE_UDMA5;
//      } else
      if (supportedUdmaModes & UDMA_MODE4)
      {
         ActiveLunConfigData.udmaMode = TRANSFER_MODE_UDMA4;
      }
      else if (supportedUdmaModes & UDMA_MODE2)
      {
         ActiveLunConfigData.udmaMode = TRANSFER_MODE_UDMA2;
      }
   }

   // Check for DMA
   if (!ActiveLunConfigData.udmaMode)
   {
      BYTE supportedDmaModes = 0;
      supportedDmaModes = EP6FIFOBUF[IDENTIFY_DMA_MODES] & DMA_MODES;

      if (bCompactFlash && !bCF_USES_UDMA)
         supportedDmaModes = 0;

      if (supportedDmaModes & DMA_MODE2)
         ActiveLunConfigData.udmaMode = TRANSFER_MODE_DMA2;
         
   }

   ActiveLunConfigData.commandSetSupport = EP6FIFOBUF[IDENTIFY_COMMAND_SET_SUPPORT];

   // We are done with EP6FIFOBUF.  reset the EP6FIFO so the internal pointers are pointing
   // back at the start of it and then re-enable interrupts.
   FIFORESET = 0x06;
   EA = oldEA;

   initDriveAfterReset();

   ActiveLunConfigData.driveCapacity -= 1;  // The command that reads drive capacity actually wants the last valid LBA.
   return;
}

void configureATATransferMode(BYTE mode)
{
   if (setFeatures(0x3, mode) == USBS_FAILED)
      if ((mode & TRANSFER_MODE_UDMA0) || (mode & TRANSFER_MODE_DMA0))
         ActiveLunConfigData.udmaMode = DeviceConfigData[currentLunNum].udmaMode = 0;
}

bit setFeatures(BYTE command, BYTE subcommand)
{
   // select the drive and set new speed
   writeATA_DRIVESEL_REG();
   waitForBusyBit();
   writePIO8(ATA_SECTOR_COUNT_REG, subcommand);      
   writePIO8(ATAPI_FEATURE_REG, command);                            // opcode 0x03 used for transfer mode
   writePIO8(ATAPI_COMMAND_REG, ATAPI_COMMAND_SET_FEATURES);      // execute the command   
   return(waitForBusyBit());
}

void ISRINT4() interrupt 10 
{
   if (!(EP01STAT & bmEP1INBSY))
      {
      EP1INBUF[0] = IOE >> 2;
      EP1INBUF[1] = ((EZUSB_HIGHSPEED()) ? 2 : 0) | VBUSPWRD;
      EP1INBC = 2;
      }
   // Clear the interrupt
   EXIF &= ~bmIE4;
}

// Timer ISR -- Cannot be placed with the other ISRs because we want the
// compiler to generate the vector.
void ISRtimer0() interrupt 1
{
   if (!hertz61ticks--)
      {
      seconds--;
      hertz61ticks = 61;
      };


   {
      // Check for ATA_ENABLE
      // check for tri-state signal on WAKEUP pin.  If it's active and we're not tristated, 
      // reset the CPU
      checkATAEnable();
   }

   if (HIDIntrfcDscrOffset && !(USBCS & bmDISCON))
      {
      BYTE buttons = (IOE & 0x7f) | ((IOA & 0x8) << 4);
      if (oldButtons != buttons)
         {
         if (!(EP01STAT & bmEP1INBSY))
            {
            EP1INBUF[0] = buttons;
            EP1INBUF[1] = ((EZUSB_HIGHSPEED()) ? 2 : 0) | VBUSPWRD;
            EP1INBC = 2;
            oldButtons = buttons;
            }
         }
      }
}

void initDriveAfterReset()
{
   // If UDMA is supported, enable it.  Then, enable the highest PIO mode
//   if (bCompactFlash)
//   {
//
//   }
//   else 
   if (ActiveLunConfigData.udmaMode)
   {
      configureATATransferMode(ActiveLunConfigData.udmaMode);
   }
   else   
   {
      // Default waveform is PIO0.  Shift up for PIO3 and PIO4
      if(ActiveLunConfigData.MaxPIO & PIO4) 
      {
         if (!ActiveLunConfigData.udmaMode)
            configureATATransferMode(PIO_MODE4);                  // SCR_PIO4=0x0C, PIO-mode4
      }
      else if(ActiveLunConfigData.MaxPIO & PIO3) 
      {
         if (!ActiveLunConfigData.udmaMode)
           configureATATransferMode(PIO_MODE3);                  // SCR_PIO3=0x0B, PIO-mode3
      }
   }

   // enable Advanced Power Management (APM) if supported by the drive and
   // specified in the configuration eeprom
   if ((ActiveLunConfigData.commandSetSupport & APM_FEATURE) &&
       (APM_VALUE))
   {
      setFeatures(SET_FEATURE_APM_ENABLE, APM_VALUE); 
   }

}

⌨️ 快捷键说明

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