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

📄 ata.c

📁 基于m128的fat16/32 和ata文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:

	// write data to drive
	ataWriteDataBuffer(Buffer, 512);

	// Wait for drive to finish write
	temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);

	// Return the error bit from the status register...
	return (temp & ATA_SR_ERR) ? 1:0;
}
#endif
////////////////////


//*****************************************************************************
// Function: ataReadSectorLBA
// Parameters: Driver, lba address, Buffer
// Returns: on Suscefull returns 0, the result errors otherwise.
//
// Description: Read one Sector (512 Bytes) from the ata dispositive
//*****************************************************************************
unsigned char ataReadSectorsLBA(	unsigned char Drive,
									unsigned long lba,
                            		unsigned char *Buffer)
{
  	unsigned int cyl, head, sect;
  	unsigned char temp;


	sect = (int) ( lba & 0x000000ffL );
	lba = lba >> 8;
	cyl = (int) ( lba & 0x0000ffff );
	lba = lba >> 16;
	head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;

	temp = ataReadSectorsCHS( Drive, head, cyl, sect, Buffer );
	return temp;
}


////////////////////
#ifndef ATA_READ_ONLY
//*****************************************************************************
// Function: ataWriteSectorsLBA
// Parameters: Driver, lba address, Buffer
// Returns: on Suscefull returns 0, the result errors otherwise.
//
// Description: Write one Sector (512 Bytes) to the ata dispositive
//*****************************************************************************
unsigned char ataWriteSectorsLBA(	unsigned char Drive,
									unsigned long lba,
									unsigned char *Buffer)
{
	unsigned int cyl, head, sect;
	unsigned char temp;

	sect = (int) ( lba & 0x000000ffL );
	lba = lba >> 8;
	cyl = (int) ( lba & 0x0000ffff );
	lba = lba >> 16;
	head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;

	temp = ataWriteSectorsCHS( Drive, head, cyl, sect, Buffer );
	return temp;
}
#endif
////////////////////


//*****************************************************************************
// Function: ataReadSectors
// Parameters: Driver, lba, Buffer, SectorInCache
// Returns: on Suscefull returns 0, the result errors otherwise.
//
// Description: Read one Sector (512 Bytes) from the ata dispositive
//*****************************************************************************
unsigned char ataReadSectors(	unsigned char Drive,
								unsigned long lba,//sector number
                            	unsigned char *Buffer,
                            	unsigned long *SectorInCache //actual sector
                            )
{
  	unsigned int cyl, head, sect;
  	unsigned char temp;


	// if the Sector is already in the memory buffer, we don't need to read the sector again
 	if(*SectorInCache==lba)
  		return 0;

	*SectorInCache=lba;

	// check if drive supports native LBA mode
	if(ataDriveInfo.LBAsupport)
	{
		// drive supports using native LBA
		temp = ataReadSectorsLBA(Drive, lba, Buffer);
	}
	else
	{
		// drive required CHS access
		// convert LBA to pseudo CHS
		// remember to offset the sector count by one
		sect = (unsigned char) (lba % ataDriveInfo.sectors)+1;
		lba = lba / ataDriveInfo.sectors;
		head = (unsigned char) (lba % ataDriveInfo.heads);
		lba = lba / ataDriveInfo.heads;
		cyl = (unsigned short) lba;

		temp = ataReadSectorsCHS( Drive, head, cyl, sect, Buffer );
	}
	return temp;
}


////////////////////
#ifndef ATA_READ_ONLY
//*****************************************************************************
// Function: ataWriteSectors
// Parameters: Driver, lba, Buffer
// Returns: on Suscefull returns 0, the result errors otherwise.
//
// Description: Write one Sector (512 Bytes) to the ata dispositive
//*****************************************************************************
unsigned char ataWriteSectors(	unsigned char Drive,
								unsigned long lba,
                            	unsigned char *Buffer)
{
  	unsigned int cyl, head, sect;
  	unsigned char temp;

	// check if drive supports native LBA mode
	if(ataDriveInfo.LBAsupport)
	{
		// drive supports using native LBA
		temp = ataWriteSectorsLBA(Drive, lba, Buffer);
	}
	else
	{
		// drive required CHS access
		// convert LBA to pseudo CHS
		// remember to offset the sector count by one
		sect = (unsigned char) (lba % ataDriveInfo.sectors)+1;
		lba = lba / ataDriveInfo.sectors;
		head = (unsigned char) (lba % ataDriveInfo.heads);
		lba = lba / ataDriveInfo.heads;
		cyl = (unsigned short) lba;

		temp = ataWriteSectorsCHS( Drive, head, cyl, sect, Buffer );
	}
	return temp;
}
#endif
////////////////////


//*****************************************************************************
// Function: ataDriveSelect
// Parameters: Drive Number
// Returns: none.
//
// Description: Change the drive, Master or Slave
//*****************************************************************************
void ataDriveSelect(unsigned char DriveNo)
{
	ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(DriveNo ? 0x10:00)); // Drive selection
}


//*****************************************************************************
// Function: ataReadByte
// Parameters: reg
// Returns: The Readed Data from the ata dispositive.
//
// Description: Read one Byte from the ata dispositive
//*****************************************************************************
unsigned char ataReadByte(unsigned char reg)
{
	register unsigned char ret;

  	PORT_DATAL= 0xFF;				// habilita pull-ups
  	DDR_DATAL  = 0x00; 		      	// Use the DATAH as an input
  	PORT_ADDR = PORT_ADDR & 0xe0; 		// Clear the lower 5 bits of the address line
  	PORT_ADDR = PORT_ADDR | (reg & 0x1f); 	// Assert the address Line

  	cbi(PORT_IDE_RD, PIN_IDE_RD);                  	// Assert DIOR
  	__asm volatile ("NOP");
  	__asm volatile ("NOP");
  	__asm volatile ("NOP");

  	ret = PIN_DATAL;
  	sbi(PORT_IDE_RD, PIN_IDE_RD);			      	// Negate DIOR

  	return (ret);
}


//*****************************************************************************
// Function: ataWriteByte
// Parameters: reg, data
// Returns: none.
//
// Description: Write one Byte to the ata dispositive
//*****************************************************************************
void ataWriteByte(unsigned char reg, unsigned char data)
{
  	DDR_DATAL = 0xff;			   	// Use DATAL an an output
  	PORT_ADDR = PORT_ADDR & 0xe0;	       		// Clear the Lower 5 bits of the Address Line
  	PORT_ADDR = PORT_ADDR | (reg & 0x1f); 	// Assert the Address line

  	PORT_DATAL = data;				// Output the data

  	cbi(PORT_IDE_WR,PIN_IDE_WR);				// Assert DIOW
  	__asm volatile ("NOP");
  	__asm volatile ("NOP");
  	__asm volatile ("NOP");
  	sbi(PORT_IDE_WR,PIN_IDE_WR);				// Negate DIOW
}



//*****************************************************************************
// Function: IDE_Wait_State
// Parameters: test_bit
// Returns: on suscefull returns 1, otherwise returns 0.
//
// Description: Test a bit in the status register
//*****************************************************************************
unsigned char IDE_Wait_State(unsigned char test_bit)
{
	if ((ataReadByte(ATA_REG_ACTSTATUS) & test_bit) == test_bit)
		return 1;
	return 0;
}



//*****************************************************************************
// Function: ataGetSizeInSectors
// Parameters: none
// Returns: Size in sectors from the ata dispositive
//
// Description: Returns the number of sectors from the ata dispositive
//*****************************************************************************
unsigned long ataGetSizeInSectors(void)
{
	return(ataDriveInfo.sizeinsectors);
}


//*****************************************************************************
// Function: ataGetSize
// Parameters: none
// Returns: Size in bytes from the ata dispositive
//
// Description: Returns the size in bytes from the ata dispositive
//*****************************************************************************
unsigned long ataGetSize(void)
{
	return(ataDriveInfo.sizeinsectors/(1000000/512));
}



//*****************************************************************************
// Function: ataGetModel
// Parameters: none
// Returns: Model string from the ata dispositive
//
// Description: Returns the model string from the ata dispositive
//*****************************************************************************
char *ataGetModel(void)
{
	return(ataDriveInfo.model);
}


//*****************************************************************************
// Function: delay
// Parameters: time in us
// Returns: none
//
// Description: delay for a minimum of <us> microseconds
// 			    the time resolution is dependent on the time the loop takes
// 	            e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us
//*****************************************************************************
void delay(unsigned short us)
{
	unsigned short delay_loops;
	register unsigned short i;

	delay_loops = (us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty)

	// one loop takes 5 cpu cycles
	for (i=0; i < delay_loops; i++) {};
}

⌨️ 快捷键说明

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