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

📄 ideutils.c

📁 MP3 Cyclone的source code 利用FPGGA實現MP3的功能
💻 C
📖 第 1 页 / 共 4 页
字号:
    printf("status register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base));
    return 0;
  }

  // Read the status register to clear INTRQ.
  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
  usError = IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base);

  if (usStatus & StatusRegBitERR)
  {
    printf("Device Diagnostic return code: 0x%X\r", 0xFF & usError);
  }
  else
  {
    // The meanings of other than bits 0 and 7 are vendor-specific.
    switch (usError & 0x81)
    {
      case 0x0:
        printf("Device 0 failed, device 1 passed or not present.\r");
        break;
      case 0x01:
        printf("Device 0 passed; device 1 passed or not present.\r");
        break;

      case 0x80:
        printf("Device 0 failed, device 1 failed.\r");
        break;

      case 0x81:
        printf("Device 0 passed, device 1 failed.\r");
        break;
      default:
        printf("unexpected case in executeDeviceDiagnostic()\r");
        break;
    }
  }

  return 1;
}

int getLogicalHeads(void)
{
  return gusLogicalHeads;
}

int getLogicalCylinders(void)
{
  return gusLogicalCylinders;
}

int getSectorsPerTrack(void)
{
  return gusSectorsPerTrack;
}

char* getModel(void)
{
  return gModel;
}


int IDE_initializeDeviceParameters(int iDevice,
  unsigned short usLogicalHeads, unsigned short usLogicalCylinders,
  unsigned short usSectorsPerTrack)
{
  unsigned short usStatus, usError;

  // a) The host reads the status or alt status reg until BSY=0.
  if (!awaitBSYZero(1000))
  {
    printf("timeout awaiting BSY=0 in initializeDeviceParameters()\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 initializeDeviceParameters()\r");
    return 0;
  }

  IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base, usSectorsPerTrack);
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
    (iDevice ? DevHeadRegBitDEV : 0) | (usLogicalHeads - 1));
  IDEinterrupt = 0;
  IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, InitializeDeviceParameters);

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

  // Read the status register to clear INTRQ.
  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
  if (usStatus & StatusRegBitERR)
  {
    usError = IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base);
    printf("Error? status: 0x%X; error: 0x%X\r", usStatus, usError);
  }
  else
  {
    if (IDE_getVerbosity())
    {
      printf("successfully wrote default parameters to IDE drive.\n");
    }
  }

  return 1;
}

void parseIdentifyDeviceBuffer(unsigned short *pusBuffer)
{
  int i;
  char *p;
  
  p = gModel;
  for (i = 27; i <= 46; ++i) {
    *p++ = (char) (pusBuffer[i] >> 8);
    *p++ = (char) (pusBuffer[i] & 0xFF);
  }

  if (gbVerbose)
  {


    printf("serial number: ");
    for (i = 10; i < 20; ++i)
    {
      printf("%c%c", pusBuffer[i] >> 8, pusBuffer[i] & 0xFF);
    }
    printf("\r");

    printf("firmware revision: ");
    for (i = 23; i < 27; ++i)
    {
      printf("%c%c", pusBuffer[i] >> 8, pusBuffer[i] & 0xFF);
    }
    printf("\r");

    printf("model number: %s\r", gModel);
  }

  if (((0x2<<8) & pusBuffer[49] ) != 0) {
    gusLBAmode = 1;
    gulLBAcapacity = pusBuffer[60] + (pusBuffer[61]<<16);
  }

  if ((0x2 & pusBuffer[64] ) != 0)
    gusPIOmode = 4;
  else if ((0x01 & pusBuffer[64] ) != 0)
    gusPIOmode = 3;
  else
    gusPIOmode = pusBuffer[51] >> 8;


  if (gusPIOmode > 4)
    gusPIOmode = 0;

  gusLogicalCylinders = pusBuffer[1];
  gusLogicalHeads = pusBuffer[3];
  gusSectorsPerTrack = pusBuffer[6];
  if (gbVerbose)
  {
    printf("LBA mode %ssupported\r", gusLBAmode ? "" : "not ");
    printf("PIO mode supported: %d\r", gusPIOmode);
    printf("device parameters:\r");
    printf(
      "  # logical cylinders: %d\r"
      "  # logical heads: %d\r"
      "  # logical sectors/track: %d\r",
      gusLogicalCylinders, gusLogicalHeads, gusSectorsPerTrack);
    if (gusLBAmode)
      printf("  LBA capacity = %u sectors\r",  (unsigned int)gulLBAcapacity);
  }
}

int IDE_identifyDevice(unsigned int uiDeviceNumber)
{
  unsigned short usStatus;
  int i;
  unsigned short usBuffer[256];

  if (gbVerbose)
  {
    printf("Identify Device:\r");
  }
#if DEBUG
  printf("\rIDE_identifyDevice()\r");
#endif // DEBUG

  // Select the device to identify.
  if (uiDeviceNumber > 1)
  {
    printf("invalid device number in IDE_identifyDevice (%d)\r",
      uiDeviceNumber);
    return 0;
  }

  if (IORD_ALTERA_AVALON_CF_CTL_STATUS(ctl_base)
            & ALTERA_AVALON_CF_CTL_STATUS_PRESENT_MSK)
  {
#if DEBUG
    printf("IDE_identifyDevice: card is inserted\r");
#endif // DEBUG
  }
  else
  {
    printf("CompactFlash card is removed\r");
    return 0;
  }

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

#if DEBUG
  printf("IDE_identifyDevice: found BSY=0\r");
#endif // DEBUG

  // b) The host writes the dev/head register with the appropriate dev
  //    bit value.
  IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base, uiDeviceNumber ? 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 IDE_identifyDevice()\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.
  // (No input parameters for Identify Device)

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

  // 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 the block of data is available, the device sets the DRQ bit
  //    (setting the DRQ bit is optional if an error condition exists).
  //    If there is an error condition, the device sets the appropriate status
  //    and error bits as required by that error condition.  Finally, the device
  //    clears BSY and then asserts INTRQ.  (Note: there may be times when BSY
  //    is set in f) and then cleared in g) so quickly that the host may not
  //    be able to detect that BSY had been set.)

  // Wait for INTRQ.
  // Empirically, I note that after a hardware reset (press SW2), it can take
  // an eternity (3.3 s) to get INTRQ here, on the Connor drive at least.
  // Use a really long timeout.
  if (!awaitINTRQ(5000))
  {
    printf("timeout awaiting INTRQ=1 in identifyDevice()\r");
    printf("error register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
    return 0;
  }

  // h) After detecting either BSY=0 (alt status) or INTRQ, the host reads and
  //    saves the contents of the status register.
  usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base); // (To clear INTRQ)
  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 & StatusRegBitDRQ)
  {
    for (i = 0; i < 256; ++i)
    {
      usBuffer[i] = IORD_ALTERA_AVALON_CF_IDE_DATA(ide_base);
    }
  }
  else
  {
    printf("DRQ not set in status reg in identifyDevice()\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.

  parseIdentifyDeviceBuffer(usBuffer);

  return 1;
}

void printSectorBuffer(unsigned long ulNumSectors, unsigned short *pusBuffer)
{
  int i, j, k;
  unsigned char ucStr[] = "0123456789012345";

  unsigned char *pucBuffer = (unsigned char*)pusBuffer;

  for (i = 0; i < ulNumSectors * 512; i += 512)
  {
    for (j = 0; j < 512; j += 16)
    {
      printf("%04X:  ", i + j);
      for (k = 0; k < 16; ++k)
      {
        printf("%02X ", pucBuffer[i + j + k]);
        if (pucBuffer[i + j + k] >= 0x20 && pucBuffer[i + j + k] <= 0x7F)
        {
          ucStr[k] = pucBuffer[i + j + k];
        }
        else
        {
          ucStr[k] = '.';
        }
      }
      printf(" %s\r", ucStr);
    }
    printf("\r");
  }
}

void randomizeBuffer(unsigned long ulNumSectors, unsigned short *usBuffer)
{
  unsigned long i;
  for (i = 0; i < 256 * ulNumSectors; ++i)
  {
    usBuffer[i] = (rand() & 0xFFFF00) >> 8;
  }
}

int multiRead(char *szArg)
{
#define MULTIPLE_SECTOR_READ 1
  int iHead, iCylinder, iSectorNumber;
  int iResult;
#if MULTIPLE_SECTOR_READ
  unsigned short *pusBuffer;
#else
  unsigned short usBuffer[256];
#endif // MULTIPLE_SECTOR_READ
  int iNumSectorsRead = 0, iNumSectorsToRead;
  volatile unsigned int uiStartTime;
  volatile unsigned int uiDeltaTime;

  if (1 != sscanf(szArg, "%d", &iNumSectorsToRead))
  {
    printf("multiRead: arg '%s' makes no sense.\r", szArg);
    return 0;
  }

#if MULTIPLE_SECTOR_READ
  pusBuffer = (unsigned short*)malloc(256 * gusSectorsPerTrack * sizeof(unsigned short));
  if (!pusBuffer)
  {
    printf("multiRead: memory allocation failure.\n");
    return 0;
  }
#endif // MULTIPLE_SECTOR_READ

  printf("reading %d sectors on device 0.  Hit any key to abort.\r", iNumSectorsToRead);

  // Flush input buffer.
#if 0
  while (-1 != nr_uart_rxchar(0))  {}
#else
  getchar();
#endif

  uiStartTime = getTime();

  // Read forever (up to the number of sectors requested, or keypress).
  while (1)
  {
    for (iCylinder = 0; iCylinder < gusLogicalCylinders; ++iCylinder)
    {
      for (iHead = 0; iHead < gusLogicalHeads; ++iHead)
      {
        // Do this checking here, rather than on a sector-by-sector basis, to
        // boost performance.
#if 0
        if (-1 != nr_uart_rxchar(0))
#else
        getchar();
#endif
        {
          goto computeStats;
        }
#if MULTIPLE_SECTOR_READ
        // Done yet?
        if (iNumSectorsRead >= iNumSectorsToRead)
        {
          goto computeStats;
        }
        iResult = readSectorsCHS(0, iCylinder, iHead, 1, gusSectorsPerTrack, pusBuffer);
        if (1 != iResult)
        {
          printf("(0, %d, %d, %d, %d) failed.\r",
            iCylinder, iHead, iSectorNumber, gusSectorsPerTrack);
        }
        else
        {
          iNumSectorsRead += gusSectorsPerTrack;

          if (gbVerbose)
          {
            printf("(0, %d, %d, %d, %d) succeeded.\r",
              iCylinder, iHead, iSectorNumber, gusSectorsPerTrack);
            printSectorBuffer(gusSectorsPerTrack, pusBuffer);
          }
        }

#else // !MULTIPLE_SECTOR_READ
        for (iSectorNumber = 1; iSectorNumber <= gusSectorsPerTrack; ++iSectorNumber)
        {
          // Done yet?
          if (iNumSectorsRead >= iNumSectorsToRead)
          {
            goto computeStats;
          }

          iResult = readSectorsCHS(0, iCylinder, iHead, iSectorNumber, 1, usBuffer);
          if (1 != iResult)
          {
            printf("(0, %d, %d, %d, 1) failed.\r",
              iCylinder, iHead, iSectorNumber);
          }
          else
          {
            iNumSectorsRead++;

            if (gbVerbose)
            {
              printf("(0, %d, %d, %d, 1) succeeded.\r",
                iCylinder, iHead, iSectorNumber);
              printSectorBuffer(1, usBuffer);
            }
          }
        }
#endif // MULTIPLE_SECTOR_READ
      }
    }
  }


computeStats:
#if MULTIPLE_SECTOR_READ
  if (pusBuffer)
  {
    free(pusBuffer);
    pusBuffer = 0;
  }
#endif // MULTIPLE_SECTOR_READ

  uiDeltaTime = getTime() - uiStartTime;
  printf("%d sectors read in %d.%d s\r",
    iNumSectorsRead, uiDeltaTime / 1000, uiDeltaTime % 1000);
  printf("at 512 bytes/sector, that's %d bytes/second\r\r",
    (int)(iNumSectorsRead * 512. * 1000 / uiDeltaTime));

  return 1;
}

int multiWrite(char *szArg)
{
#define MULTIPLE_SECTOR_WRITE 1

  int iHead, iCylinder, iSectorNumber;
  int iResult;
#if MULTIPLE_SECTOR_WRITE
  unsigned short *pusBuffer;
#else // !MULTIPLE_SECTOR_WRITE
  unsigned short usBuffer[256];
#endif // MULTIPLE_SECTOR_WRITE
  int iNumSectorsWritten = 0, iNumSectorsToWrite;
  volatile unsigned int uiStartTime;
  volatile unsigned int uiDeltaTime;

  if (1 != sscanf(szArg, "%d", &iNumSectorsToWrite))
  {
    printf("multiWrite: arg '%s' makes no sense.\r", szArg);

⌨️ 快捷键说明

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