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

📄 ideutils.c

📁 MP3 Cyclone的source code 利用FPGGA實現MP3的功能
💻 C
📖 第 1 页 / 共 4 页
字号:
    usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);

    // i) If DRQ=1, the host transfers a block of data by reading the Data register.
    //    If any error conditions are present in the status read in step h), the
    //    data transfer may not be valid.
    if (usStatus & AltStatusRegBitDRQ)
    {
        for (i = 0; i < 256; ++i)
        {
          iIndex = i + 256 * iSect;
          // printf("writing byte at index %d\r", iIndex);
          pusBuffer[iIndex] = IORD_ALTERA_AVALON_CF_IDE_DATA(ide_base);
        }
    }
    else
    {
      printf("DRQ not set in status reg in readSectorsCHS()\r");
      return 0;
    }

    // j) When the status register is read, the device negates INTRQ.  In response to
    //    the complete data block being read, one of the following actions is taken:
    //    - if no error status was presented to the host in step h), and if transfer
    //      of another block is required, the device sets BSY and the above sequence
    //      is repeated starting from step g).
    //    - If an error status was present in the status read in step h), the device
    //      clears DRQ and the command execution is complete.
    //    - If the last block was transfered, the device clears DRQ and the command
    //      execution is complete.
  }

 return 1;
}


int readSectorsCHS(int iDevice, int iCylinder, int iHead, int iSectorNumber,
    int iSectorCount, unsigned short *pusBuffer)
{
  if (gbVerbose)
  {
    printf("CHS = (%d, %d, %d); numSectors: %d\r",
      iCylinder, iHead, iSectorNumber, iSectorCount);
  }

  // 1: set up the request.
  if (!PIODataInOrOutPreamble(iDevice))
  {
    printf("readSectorsCHS(): PIODataInOrOutPreamble failed.\r");
    return 0;
  }

  // d) The host writes any required command parameters to the Features,
  //    Sector Count, Sector Number, Cylinder High, Cylinder Low and
  //    Device/Head registers.
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base,  iSectorCount);
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, iSectorNumber);
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base,  iCylinder & 0xFF);
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, iCylinder >> 8);
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
    (iDevice ? DevHeadRegBitDEV : 0) |
    (iHead & DevHeadRegBitHeads));

  // e) The host writes the command code to the Command register.
  IDEinterrupt = 0;
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, ReadSectorWithRetries);

  // 2: wait for and read the data.
  return readSectorsCHSResult(iSectorCount, pusBuffer);
}


int readSectorsLBA(int iDevice, unsigned long ulLBA,
    int iSectorCount, unsigned short *pusBuffer)
{
  if (gbVerbose)
  {
    printf("LBA = %u; numSectors: %d\r", (unsigned int)ulLBA, iSectorCount);
  }

  // 1: set up the request.
  if (!PIODataInOrOutPreamble(iDevice))
  {
    printf("readSectorsLBA(): PIODataInOrOutPreamble failed.\r");
    return 0;
  }

  // d) The host writes any required command parameters to the Features,
  //    Sector Count, Sector Number, Cylinder High, Cylinder Low and
  //    Device/Head registers.
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base,  iSectorCount);

  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base,  ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base, (ulLBA & 0x0F) | 0xE0 |  // LBA on
    (iDevice ? DevHeadRegBitDEV : 0));

  // e) The host writes the command code to the Command register.
  IDEinterrupt = 0;
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, ReadSectorWithRetries);

  // 2: wait for and read the data.
  return readSectorsCHSResult(iSectorCount, pusBuffer);
}


int writeSectorsLBA(int iDevice, unsigned long ulLBA,
    int iSectorCount, unsigned short *pusBuffer)
{
  unsigned short usStatus;
  int i;
  int iNumSectorsWritten = 0;

  if (gbVerbose)
  {
    printf("LBA = %u; numSectors: %d\r", (unsigned int)ulLBA, iSectorCount);
  }

  if (!PIODataInOrOutPreamble(iDevice))
  {
    printf("writeSectorsLBA(): PIODataInOrOutPreamble failed.\r");
    return 0;
  }

  // d) The host writes any required command parameters to the Features,
  //    Sector Count, Sector Number, Cylinder High, Cylinder Low and
  //    Device/Head registers.
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base,  iSectorCount);
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base,  ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, ulLBA & 0xFF);
  ulLBA >>= 8;
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,  (ulLBA & 0x0F) | 0xE0 |  // LBA on
    (iDevice ? DevHeadRegBitDEV : 0));

  // e) The host writes the command code to the Command register.
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, WriteSectorWithRetries);

  // f) The device sets the BSY bit and prepares to execute the command
  //    including preparation to transfer the first block of data to the
  //    host.  (Note: it may take up to 400ns for BSY to go high.)
  usleep(1);

  // g) When ready to receive the first block of data from the host, the device
  //    sets the DRQ bit (setting the DRQ bit is optional if an error condition
  //    exists) and any other status or error bits as required and clears the BSY
  //    bit.
  // h) The host reads the status or alternate status register until BSY is
  //    equal to 0.
  if (!awaitBSYZero(1000))
  {
    printf("timeout (2) awaiting BSY=0 in writeSectorsLBA()\r");
    return 0;
  }
  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);

  // i) If the DRQ bit is set, the host transfers a complete block of data to
  //    the device by writing the Data register.
  usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
  if (usStatus & StatusRegBitDRQ)
  {
    for (i = 0; i < 256; ++i)
    {
      IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base, pusBuffer[i]);
    }
  }
  else
  {
    printf("writeSectorsLBA(): error: DRQ not set.\r");
    return 0;
  }

  // j) Next, one of the following actions is taken:
  // - if an error status was present in the status read in step h), the device
  //   clears the DRQ bit, asserts INTRQ and the command execution is complete.
  //   The data transferred in steup i) is not processed by the device.
  // - if no error status was presented to the host in step h), the device sets
  //   the BSY bit and processing continues with the next step.
  if (usStatus & AltStatusRegBitERR)
  {
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base); // Clear INTRQ
    printf("error occurred during write (error reg: 0x%X)\r",
      IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
    return 0;
  }

#if 0
  // Oddly, the QUANTUM FIREBALLP LM20.4 times out here.  Also oddly,
  // removing this test makes things work fine.
  if (!awaitBSYOne(1000))
  {
    printf("writeSectorsLBA(): timeout awaiting BSY=1\r");
    return 0;
  }
#endif // 0

  iNumSectorsWritten++;

  while (1)
  {
    // k) The device processes the data block just received from the host.  When
    //   this processing is completed, one of the following actions is taken:
    //   - If no error occurred while processing the data block and if no additional
    //     blocks are to be transferred, the device clears the BSY bit and then
    //     asserts INTRQ.  Command execution is complete;
    //   -  If an error occured while processing the data block the device sets the
    //      appropriate bits as required by the error condition.  The device clears
    //      the BSY bit and then asserts INTRQ.  Command execution is complete.
    //   - If no error occurred while processing the data block and if the transfer
    //      of another block is required, processing continues with the next step.

    if (!awaitBSYZero(1000))
    {
      printf("timeout (3) awaiting BSY=0 in writeSectorsLBA()\r");
      return 0;
    }

    // Clear INTRQ.
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
    if (usStatus & StatusRegBitERR)
    {
      printf("writeSectorsLBA(): error register = 0x%X\r",
        IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
      return 0;
    }

    if (iNumSectorsWritten >= iSectorCount)
    {
      return 1;
    }

    // l) When ready to receive the next block from the host, the device sets the
    //    DRQ bit, clears the BSY bit and then asserts INTRQ;
    if (!awaitDRQ(1000))
    {
      printf("writeSectorsLBA(): timeout awaiting DRQ for multiple sector write.\r");
      return 0;
    }

    // m) After detecting either BSY=0 (alternate status) or INTRQ, the host reads
    //    the contents of the status register.
    if (!awaitBSYZeroOrINTRQ(1000))
    {
      printf("timeout awaiting BSY=0 or INTRQ in writeSectorsLBA()\r");
      return 0;
    }
#if 0
    if (!awaitBSYZero(1000))
    {
      printf("timeout (4) awaiting BSY=0 in writeSectorsLBA()\r");
      return 0;
    }

    if (!awaitINTRQ(1000))
    {
      printf("timeout awaiting INTRQ in writeSectorsCHS()\r");
      // return 0;
    }
#endif
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);

    // The host transfers a complete block of data to the device by writing
    //   the data register
    for (i = 0; i < 256; ++i)
    {
      IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base, pusBuffer[i + iNumSectorsWritten * 256]);
    }
    // o) The device sets the BSY bit and processing continues at step k).
    iNumSectorsWritten++;
  }

 return 1;
}


  // PIO Data out:
  // a) The host reads the status or alt status reg until BSY=0.
  // b) The host writes the dev/head register with the appropriate dev
  //    bit value.
  // c) The host reads the status or alt status register until BSY=0 and
  //    DRDY=1.
int writeSectorsCHS(int iDevice, int iCylinder, int iHead, int iSectorNumber,
    int iSectorCount, unsigned short *pusBuffer)
{
  unsigned short usStatus;
  int i;
  int iNumSectorsWritten = 0;

  if (gbVerbose)
  {
    printf("(%d, %d, %d)\r",
      iCylinder, iHead, iSectorNumber);
  }

  if (!PIODataInOrOutPreamble(iDevice))
  {
    printf("writeSectorsCHS(): PIODataInOrOutPreamble failed.\r");
    return 0;
  }

  // d) The host writes any required command parameters to the Features,
  //    Sector Count, Sector Number, Cylinder High, Cylinder Low and
  //    Device/Head registers.
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base,  iSectorCount);
  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, iSectorNumber);
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base,  iCylinder & 0xFF);
  IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, iCylinder >> 8);
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
    (iDevice ? DevHeadRegBitDEV : 0) |
    (iHead & DevHeadRegBitHeads));

  // e) The host writes the command code to the Command register.
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, WriteSectorWithRetries);

  // f) The device sets the BSY bit and prepares to execute the command
  //    including preparation to transfer the first block of data to the
  //    host.  (Note: it may take up to 400ns for BSY to go high.)
  usleep(1);

  // g) When ready to receive the first block of data from the host, the device
  //    sets the DRQ bit (setting the DRQ bit is optional if an error condition
  //    exists) and any other status or error bits as required and clears the BSY
  //    bit.
  // h) The host reads the status or alternate status register until BSY is
  //    equal to 0.
  if (!awaitBSYZero(1000))
  {
    printf("timeout (2) awaiting BSY=0 in writeSectorsCHS()\r");
    return 0;
  }
  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);

  // i) If the DRQ bit is set, the host transfers a complete block of data to
  //    the device by writing the Data register.
  usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
  if (usStatus & StatusRegBitDRQ)
  {
    for (i = 0; i < 256; ++i)
    {
      IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base, pusBuffer[i]);
    }
  }
  else
  {
    printf("writeSectorsCHS(): error: DRQ not set.\r");
    return 0;
  }

  // j) Next, one of the following actions is taken:
  // - if an error status was present in the status read in step h), the device
  //   clears the DRQ bit, asserts INTRQ and the command execution is complete.
  //   The data transferred in steup i) is not processed by the device.
  // - if no error status was presented to the host in step h), the device sets
  //   the BSY bit and processing continues with the next step.
  if (usStatus & AltStatusRegBitERR)
  {
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base); // Clear INTRQ
    printf("error occurred during write (error reg: 0x%X)\r",
      IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
    return 0;
  }

#if 0
  // Oddly, the QUANTUM FIREBALLP LM20.4 times out here.  Also oddly,
  // removing this test makes things work fine.
  if (!awaitBSYOne(1000))
  {
    printf("writeSectorsCHS(): timeout awaiting BSY=1\r");
    return 0;
  }
#endif // 0

  iNumSectorsWritten++;

  while (1)
  {
    // k) The device processes the data block just received from the host.  When
    //   this processing is completed, one of the following actions is taken:
    //   - If no error occurred while processing the data block and if no additional
    //     blocks are to be transferred, the device clears the BSY bit and then
    //     asserts INTRQ.  Command execution is complete;
    //   -  If an error occured while processing the data block the device sets the
    //      appropriate bits as required by the error condition.  The device clears
    //      the BSY bit and then asserts INTRQ.  Command execution is complete.
    //   - If no error occurred while processing the data block and if the transfer
    //      of another block is required, processing continues with the next step.

    if (!awaitBSYZero(1000))
    {
      printf("timeout (3) awaiting BSY=0 in writeSectorsCHS()\r");
      return 0;
    }

    // Clear INTRQ.
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
    if (usStatus & StatusRegBitERR)
    {
      printf("writeSectorsCHS(): error register = 0x%X\r",
        IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
      return 0;
    }

    if (iNumSectorsWritten >= iSectorCount)
    {
      return 1;
    }

    // l) When ready to receive the next block from the host, the device sets the
    //    DRQ bit, clears the BSY bit and then asserts INTRQ;
    if (!awaitDRQ(1000))
    {
      printf("writeSectorsCHS(): timeout awaiting DRQ for multiple sector write.\r");
      return 0;
    }

    // m) After detecting either BSY=0 (alternate status) or INTRQ, the host reads
    //    the contents of the status register.
    if (!awaitBSYZeroOrINTRQ(1000))
    {
      printf("timeout awaiting BSY=0 or INTRQ in writeSectorsCHS()\r");
      return 0;
    }
#if 0
    if (!awaitBSYZero(1000))
    {
      printf("timeout (4) awaiting BSY=0 in writeSectorsCHS()\r");
      return 0;
    }

    if (!awaitINTRQ(1000))
    {
      printf("timeout awaiting INTRQ in writeSectorsCHS()\r");
      // return 0;
    }
#endif
    usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);

    // The host transfers a complete block of data to the device by writing
    //   the data register
    for (i = 0; i < 256; ++i)
    {
      IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base, pusBuffer[i + iNumSectorsWritten * 256]);
    }
    // o) The device sets the BSY bit and processing continues at step k).
    iNumSectorsWritten++;
  }

 return 1;
}

int executeDeviceDiagnostic(int iDevice)
{
  unsigned short usStatus, usError;

  // a) The host reads the status or alt status reg until BSY=0.
  if (!awaitBSYZero(1000))
  {
    printf("timeout (1) awaiting BSY=0 in executeDeviceDiagnostic()\r");
    return 0;
  }

  // b) The host writes the dev/head register with the appropriate dev
  //    bit value.
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base, iDevice ? DevHeadRegBitDEV : 0);

  // c) The host reads the status or alt status register until BSY=0 and
  //    DRDY=1.
  if (!awaitBSYZeroDRDYOne())
  {
    printf("timeout awaiting BSY=0, DRDY=1 in executeDeviceDiagnostic()\r");
    return 0;
  }

  IDEinterrupt = 0;
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, ExecuteDeviceDiagnostic);
  usleep(1);

  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
  if (StatusRegBitERR & usStatus)
  {
    printf("Error? error register: 0x%X\r",
      IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
  }

  // Wait for BSY=0.  This one takes seconds!

  if (!awaitBSYZero(3000))
  {
    printf("timeout (2) awaiting BSY=0 in executeDeviceDiagnostic()\r");
    return 0;
  }

  // Wait for INTRQ.
  if (!awaitINTRQ(5000))
  {
    printf("timeout awaiting INTRQ=1 in executeDeviceDiagnostic()\r");
    printf("error register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));

⌨️ 快捷键说明

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