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

📄 ata.c

📁 PDA上的包含NANDFlash和FAT文件系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
#ifdef PCMCIA_DEBUG
	printString("ATA_READ_SECTOR: step 0 error\n\r");
#endif
        return ATA_FAILURE;
  }

  // 1. SELECT THE DISK-CONTROLLER
  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
        //	status = (unsigned short)secCount;
        //	status = status << 8;
        //	status |= (unsigned short)readSec.Sector;
  	//#else
        	status = (unsigned short)readSec.Sector;
        	status = status << 8;
        	status |= (unsigned short)secCount;
        //#endif

        pcmOutport(driver + COUNT_REG, status);

  #else
        outportb(driver + COUNT_REG, secCount); // if secCount = 0, then it means 256 sectors
        outportb(driver + SECTOR_REG, readSec.Sector);
  #endif

  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
	//        status = (unsigned short)readSec.CylLow;
        //	status = status << 8;
	//        status |= (unsigned short)readSec.CylHigh;
  	//#else
	        status = (unsigned short)readSec.CylHigh;
        	status = status << 8;
	        status |= (unsigned short)readSec.CylLow;
        //#endif

        pcmOutport(driver + CYLINDER_L_REG, status);

  #else
        outportb(driver + CYLINDER_L_REG, readSec.CylLow);
        outportb(driver + CYLINDER_H_REG, readSec.CylHigh);
  #endif

  // 2. Wait for the time ATA-Register can accept COMMAND
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
  {
#ifdef PCMCIA_DEBUG
	printString("ATA_READ_SECTOR: step 2 error\n\r");
#endif
        return ATA_FAILURE;
  }

  // 3. Send Read command to ata-controller
  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
	//        status = ((unsigned short)ATA_MASTER_DRV | (unsigned short)readSec.Head);
        //	if (FATIsLBA != FALSE)
	//                status |= (unsigned short)ATA_LBA_MODE;

        //	status = status << 8;
	//        status |= (unsigned short)READ_ATA_CMD;
  	//#else
	        status = (unsigned short)READ_ATA_CMD;
        	status = status << 8;
	        status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)readSec.Head);
        	if (FATIsLBA != FALSE)
	                status |= (unsigned short)ATA_LBA_MODE;
        //#endif
        pcmOutport(driver + DEV_HEADER_REG, status);

  #else
        if (FATIsLBA == FALSE)
                outportb(driver + DEV_HEADER_REG, (readSec.Head | ATA_MASTER_DRV));
        else
                outportb(driver + DEV_HEADER_REG, (readSec.Head | (ATA_MASTER_DRV | ATA_LBA_MODE)));

        outportb(driver + COMMAND_REG, READ_ATA_CMD);
  #endif


    base = (unsigned short*)CF_TASK_FILE_ADDR;
    base += ((driver + DATA_REG)&0xFFFE);
    base = (unsigned short*)((int)base | 0x00000002);
    // 4. Looping for reading "secCount" sectors
    while (secCount != 0)
    {
          status = WAIT_COMMAND_RESULT(driver, FAT_TIMEOUT * TICK_HZ);

          if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DATA_READY) != ATA_DATA_READY))
          {
                  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_COMMAND_ERROR) == ATA_COMMAND_ERROR))
                  {
		  #ifdef PCMCIA_DEBUG
			  printString("ATA_READ_SECTOR: step 4 error\n\r");
		  #endif
                          return ATA_FAILURE;
                  }
          }

          // Move one sector (512 bytes) to caller's dataBuffer
          pcmMoveDataFixSrc( base , buf , WORDS_PER_SECTOR );
          secCount--;
          buf += WORDS_PER_SECTOR;
    }

  return GET_ERROR_RESULT(driver);
#endif
}

/*************************************************************
Function: ATA_WRITE_SECTOR
        Write N sectors to drive
**************************************************************/
unsigned short ATA_WRITE_SECTOR(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
#ifdef FAT_USE_SMC//thhuang added
	unsigned long i;
	unsigned short status;

  	if( secCount <= 0 )
    		return ATA_OK;

	if ( (startSec & (NFLASH_FRAMES_OF_BLOCK-1)) != 0 )
	{
		if ( (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) < (startSec+secCount-1) )
		{
			status = LG_write_block( startSec, startSec | (NFLASH_FRAMES_OF_BLOCK-1), buf );//not over
			if ( status == NFLASH_FAIL )
				return ATA_FAILURE;//failure, so it's over...

			secCount -= (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) - startSec + 1;
			buf += WORDS_PER_SECTOR*((startSec | (NFLASH_FRAMES_OF_BLOCK-1)) - startSec + 1);
			startSec = (startSec | (NFLASH_FRAMES_OF_BLOCK-1)) + 1;//next block.
		}
		else
		{
			if ( LG_write_block( startSec, startSec+secCount-1 , buf ) == NFLASH_OK )
				return ATA_OK;//end
			else
				return ATA_FAILURE;//end
		}
	}

	/* Now the startSec points to the start of a block */
	for ( i = startSec;  i < (startSec+secCount); i+=NFLASH_FRAMES_OF_BLOCK )
	{
		if ( (i+NFLASH_FRAMES_OF_BLOCK) < (startSec+secCount) )
		{
			status = LG_write_block( i, i | (NFLASH_FRAMES_OF_BLOCK-1), buf );//not over
			if ( status == NFLASH_FAIL )
				return ATA_FAILURE;//failure, so it's over...
		}
		else
		{
			if ( LG_write_block( i, startSec+secCount-1, buf ) == NFLASH_OK )
				return ATA_OK;//end
			else
				return ATA_FAILURE;//end
		}
		buf += WORDS_PER_SECTOR*NFLASH_FRAMES_OF_BLOCK;
	}
	return ATA_OK;
#elif defined FAT_USE_MMC
	unsigned char i;

	for ( i=0 ; i<secCount; i++ )
	{
		if ( MMC_EraseSector( startSec+i,  startSec+i ) != SM_OK )
			return ATA_FAILURE;
		if ( MMC_WriteSector( (unsigned int *) (buf+i*WORDS_PER_SECTOR), startSec+i ) != SM_OK )
			return ATA_FAILURE;
	}
	return ATA_OK;
#else
  struct FAT_C_H_S writeSec;
  unsigned short status;
  unsigned short* base;
  int i;

  if( secCount <= 0 )
    return ATA_OK;

  FAT_logical_sector_to_chs(startSec, &writeSec);

  /* 0. Wait for the time ATA-Register can accept COMMAND */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if ((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY)
  {
#ifdef PCMCIA_DEBUG
	printString("ATA_WRITE_SECTOR: step 0 error\n\r");
#endif
        return ATA_FAILURE;
  }

  /* 1. SELECT THE DISK-CONTROLLER */
  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
        //	status = (unsigned short)secCount;
	//        status = status << 8;
	//        status |= (unsigned short)writeSec.Sector;
  	//#else
	        status = (unsigned short)writeSec.Sector;
	        status = status << 8;
        	status |= (unsigned short)secCount;
        //#endif

#ifdef PCMCIA_DEBUG
        sprintf(debugString, "W_COUNT_REG: %x", status);
        printStringLn(debugString);
#endif
        pcmOutport(driver + COUNT_REG, status);

  #else
        outportb(driver + COUNT_REG, secCount); // if secCount = 0, then it means 256 sectors
        outportb(driver + SECTOR_REG, writeSec.Sector);
  #endif

  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
	//        status = (unsigned short)writeSec.CylLow;
        //	status = status << 8;
	//        status |= (unsigned short)writeSec.CylHigh;
  	//#else
	        status = (unsigned short)writeSec.CylHigh;
        	status = status << 8;
	        status |= (unsigned short)writeSec.CylLow;
        //#endif

#ifdef PCMCIA_DEBUG
        sprintf(debugString, "W_CYL_L_REG: %x", status);
        printStringLn(debugString);
#endif
        pcmOutport(driver + CYLINDER_L_REG, status);

#ifdef PCMCIA_DEBUG
        sprintf(debugString, "R_CYL_L_REG: %x",
        	pcmInport(driver + CYLINDER_L_REG));
        printStringLn(debugString);
#endif

  #else
        outportb(driver + CYLINDER_L_REG, writeSec.CylLow);
        outportb(driver + CYLINDER_H_REG, writeSec.CylHigh);
  #endif

  /* 2. Wait for the time ATA-Register can accept COMMAND */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
  {
#ifdef PCMCIA_DEBUG
	printString("ATA_WRITE_SECTOR: step 2 error\n\r");
#endif

        return ATA_FAILURE;
  }

  /* 3. Send Write command to ata-controller */
  #ifdef FAT_USE_PCMCIA
  	//#ifdef BIG_ENDIAN
	//        status = ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
        //	if (FATIsLBA != FALSE)
        //        	status |= (unsigned short)ATA_LBA_MODE;

        //	status = status << 8;
	//        status |= (unsigned short)WRITE_ATA_CMD;
  	//#else
	        status = (unsigned short)WRITE_ATA_CMD;
        	status = status << 8;
	        status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
        	if (FATIsLBA != FALSE)
                	status |= (unsigned short)ATA_LBA_MODE;

        //#endif

#ifdef PCMCIA_DEBUG
        sprintf(debugString, "W_DEV_HEADER_REG: %x", status);
        printStringLn(debugString);
#endif

        pcmOutport(driver + DEV_HEADER_REG, status);

#ifdef PCMCIA_DEBUG
        sprintf(debugString, "R_DEV_HEADER_REG: %x",
        	pcmInport(driver + DEV_HEADER_REG));
        printStringLn(debugString);
#endif

  #else
        if (FATIsLBA == FALSE)
                outportb(driver + DEV_HEADER_REG, (writeSec.Head | ATA_MASTER_DRV));
        else
                outportb(driver + DEV_HEADER_REG, (writeSec.Head | (ATA_MASTER_DRV | ATA_LBA_MODE)));

        outportb(driver + COMMAND_REG, WRITE_ATA_CMD);
  #endif

    base = (unsigned short*)CF_TASK_FILE_ADDR;
    base += ((driver + DATA_REG)&0xFFFE);
    //base = (unsigned short*)((int)base | 0x00000002);
  /* 4. Looping for writing "secCount" sectors */
  while (secCount != 0)
  {
  	status = WAIT_COMMAND_RESULT(driver, FAT_TIMEOUT * TICK_HZ);

        if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DATA_READY) != ATA_DATA_READY))
        {
        	if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_COMMAND_ERROR) == ATA_COMMAND_ERROR))
                {
                #ifdef PCMCIA_DEBUG
                	printString("ATA_WRITE_SECTOR: step 4 error\n\r");
                #endif

                        return ATA_FAILURE;
                }
        }
        pcmMoveDataFixDest( buf , base , WORDS_PER_SECTOR );
        secCount--;
        buf += WORDS_PER_SECTOR;
  }

  return GET_ERROR_RESULT(driver);
#endif //not SMC
}

/*************************************************************
Function: ATA_ERASE_SECTOR
        Erase N sectors to drive
**************************************************************/
unsigned short ATA_ERASE_SECTOR(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
#ifdef FAT_USE_PCMCIA

  struct FAT_C_H_S writeSec;
  unsigned short status;
  unsigned short* base;
  int i;

  if( secCount <= 0 )
    return ATA_OK;

  FAT_logical_sector_to_chs(startSec, &writeSec);

  /* 0. Wait for the time ATA-Register can accept COMMAND */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if ((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY)
  {
        return ATA_FAILURE;
  }

  /* 1. SELECT THE DISK-CONTROLLER */

	status = (unsigned short)writeSec.Sector;
	status = status << 8;
	status |= (unsigned short)secCount;
	pcmOutport(driver + COUNT_REG, status);


	status = (unsigned short)writeSec.CylHigh;
	status = status << 8;
	status |= (unsigned short)writeSec.CylLow;
	
	pcmOutport(driver + CYLINDER_L_REG, status);

  /* 2. Wait for the time ATA-Register can accept COMMAND */
  status = WAIT_COMMAND_AVAILABLE(driver, FAT_TIMEOUT * TICK_HZ);

  if (((status & ATA_COMMAND_BUSY) == ATA_COMMAND_BUSY) || ((status & ATA_DRIVE_READY) != ATA_DRIVE_READY))
  {

        return ATA_FAILURE;
  }

  /* 3. Send Write command to ata-controller */

	status = (unsigned short)0x00c0;//Erase
	status = status << 8;
	status |= ((unsigned short)ATA_MASTER_DRV | (unsigned short)writeSec.Head);
	if (FATIsLBA != FALSE)
		status |= (unsigned short)ATA_LBA_MODE;

    pcmOutport(driver + DEV_HEADER_REG, status);


  return GET_ERROR_RESULT(driver);
#endif
}


/*************************************************************
Function: ATA_READ
**************************************************************/
unsigned short ATA_READ(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
	unsigned short status;

	/* Kevin, change SDRAM hold time for CF access */
#if defined(PR2001B)||defined(AR2001)
	*(unsigned char *) 0xbfbf001c |= 0x20;
#endif
	status = ATA_READ_SECTOR(driver, secCount, startSec, buf);
#if defined(PR2001B)||defined(AR2001)
	*(unsigned char *) 0xbfbf001c &= ~(0x20);
#endif

	return status;
}

/*************************************************************
Function: ATA_WRITE
**************************************************************/
unsigned short ATA_WRITE(int driver, unsigned char secCount, unsigned long startSec, unsigned short *buf)
{
	unsigned short status;

	/* Kevin, change SDRAM hold time for CF access */
#if defined(PR2001B)||defined(AR2001)
	*(unsigned char *) 0xbfbf001c |= 0x20;
#endif
	status = ATA_WRITE_SECTOR(driver, secCount, startSec, buf);
#if defined(PR2001B)||defined(AR2001)
	*(unsigned char *) 0xbfbf001c &= ~(0x20);
#endif
	return status;
}

#endif //FAT_ID

⌨️ 快捷键说明

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