?? ata.c
字號(hào):
// 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++) {};
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -