📄 ata_if.c
字号:
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned char temp;
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// Prepare parameters...
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track
ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track
ataWriteByte(ATA_REG_STARTSEC, Sector); // sector
ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
// Issue write sector command
ataWriteByte(ATA_REG_CMDSTATUS1, 0x31);
//delay(100);
//delay(100);
// Wait for drive to request data transfer
ataStatusWait(ATA_SR_DRQ, 0);
// write data to drive
ataWriteDataBuffer(Buffer, 512*numsectors);
// Wait for drive to finish write
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// check for errors
if (temp & ATA_SR_ERR)
{
uartPrintStr("WR ERR\r\n");
return 1;
}
// Return the error bit from the status register...
return (temp & ATA_SR_ERR) ? 1:0;
}
unsigned char ataReadSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
uartPrintStr("ATA LBA read ");
uartPrintfu32(lba); uartPrintStr(" ");
uartPrintfu16(numsectors); uartPrintStr(" ");
uartPrintfu16((unsigned int)Buffer);
uartPrintStr("\r\n");
#endif
sect = (int) ( lba & 0x000000ffL );
lba = lba >> 8;
cyl = (int) ( lba & 0x0000ffff );
lba = lba >> 16;
head = ( (int) ( lba & 0x0fL ) ) | 0x40;
temp = ataReadSectors( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataWriteSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
uartPrintStr("ATA LBA write ");
uartPrintfu32(lba); uartPrintStr(" ");
uartPrintfu16(numsectors); uartPrintStr(" ");
uartPrintfu16((unsigned int)Buffer);
uartPrintStr("\r\n");
#endif
sect = (int) ( lba & 0x000000ffL );
lba = lba >> 8;
cyl = (int) ( lba & 0x0000ffff );
lba = lba >> 16;
head = ( (int) ( lba & 0x0fL ) ) | 0x40;
temp = ataWriteSectors( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataReadSectorsLBAforCHS( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
// do this defore destroying lba
uartPrintStr("ATA LBA for CHS read: ");
uartPrintStr("LBA="); uartPrintfu32(lba); uartPrintStr(" ");
#endif
// convert LBA to pseudo CHS
sect = (u08) (lba % ataDiskParam.sectors)+1;
lba = lba / ataDiskParam.sectors;
head = (u08) (lba % ataDiskParam.heads);
lba = lba / ataDiskParam.heads;
cyl = (u16) lba;
#ifdef DEBUG_ATA
uartPrintStr("C:H:S=");
uartPrintfu16(cyl); uartPrintStr(":");
uartPrintfu08(head); uartPrintStr(":");
uartPrintfu08(sect); uartPrintStr("\r\n");
//uartPrintfu16(numsectors); uartPrintStr(" ");
//uartPrintfu16((unsigned int)Buffer);
//uartPrintStr("\r\n");
#endif
temp = ataReadSectors( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataWriteSectorsLBAforCHS( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
// do this defore destroying lba
uartPrintStr("ATA LBA for CHS write: ");
uartPrintStr("LBA="); uartPrintfu32(lba); uartPrintStr(" ");
#endif
// convert LBA to pseudo CHS
sect = (u08) (lba % ataDiskParam.sectors)+1;
lba = lba / ataDiskParam.sectors;
head = (u08) (lba % ataDiskParam.heads);
lba = lba / ataDiskParam.heads;
cyl = (u16) lba;
#ifdef DEBUG_ATA
uartPrintStr("C:H:S=");
uartPrintfu16(cyl); uartPrintStr(":");
uartPrintfu08(head); uartPrintStr(":");
uartPrintfu08(sect); uartPrintStr("\r\n");
//uartPrintfu16(numsectors); uartPrintStr(" ");
//uartPrintfu16((unsigned int)Buffer);
//uartPrintStr("\r\n");
#endif
temp = ataWriteSectors( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
//----------------------------------------------------------------------------
// Set drive mode (STANDBY, IDLE)
//----------------------------------------------------------------------------
/*#define STANDBY 0
#define IDLE 1
#define SLEEP 2
*/
/*
unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown)
{
WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
WriteBYTE(CMD, 2, (PwrDown ? 0x01:0x00)); // Enable automatic power down
switch (Mode)
{
case STANDBY: WriteBYTE(CMD,7, 0xE2); break;
case IDLE: WriteBYTE(CMD,7, 0xE3); break;
// NOTE: To recover from sleep, either issue a soft or hardware reset !
// (But not on all drives, f.ex seagate ST3655A it's not nessecary to reset
// but only to go in Idle mode, But on a Conner CFA170A it's nessecary with
// a reset)
case SLEEP: WriteBYTE(CMD,7, 0xE6); break;
}
Timer10mSec=10000;
while ((ReadBYTE(CMD,7) & 0xC0)!=0x40 && Timer10mSec); // Wait for DRDY & NOT BUSY
if (Timer10mSec==0) return 0xFF; // or timeout
// Return the error register...
return ReadBYTE(CMD, 1);
}
*/
u08 ataReadByte(u08 reg)
{
register u08 ret;
sbi(MCUCR, SRW); // enable RAM waitstate
ret = *((volatile unsigned char*) ATA_REG_BASE + reg);
cbi(MCUCR, SRW); // disable RAM waitstate
return ret;
}
void ataWriteByte(u08 reg, u08 data)
{
sbi(MCUCR, SRW); // enable RAM waitstate
*((volatile unsigned char*) ATA_REG_BASE + reg) = data;
cbi(MCUCR, SRW); // disable RAM waitstate
}
// ----------------------------------------------------------------------------
// Show all IDE registers
// ----------------------------------------------------------------------------
void ataShowRegisters(unsigned char DriveNo)
{
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
uartPrintStr("Reg 0="); uartPrintfu08(ataReadByte(ATA_REG_DATAL )); uartPrintStr(" ");
uartPrintStr("1="); uartPrintfu08(ataReadByte(ATA_REG_ERROR )); uartPrintStr(" ");
uartPrintStr("2="); uartPrintfu08(ataReadByte(ATA_REG_SECCOUNT)); uartPrintStr(" ");
uartPrintStr("3="); uartPrintfu08(ataReadByte(ATA_REG_STARTSEC)); uartPrintStr(" ");
uartPrintStr("4="); uartPrintfu08(ataReadByte(ATA_REG_CYLLO )); uartPrintStr(" ");
uartPrintStr("5="); uartPrintfu08(ataReadByte(ATA_REG_CYLHI )); uartPrintStr(" ");
uartPrintStr("6="); uartPrintfu08(ataReadByte(ATA_REG_HDDEVSEL)); uartPrintStr(" ");
uartPrintStr("7="); uartPrintfu08(ataReadByte(ATA_REG_CMDSTATUS1)); uartPrintStr("\n\r");
}
unsigned char ataSWReset(void)
{
ataWriteByte(ATA_REG_HDDEVSEL, 0x06); // SRST and nIEN bits
delay(10); // 10uS delay
ataWriteByte(ATA_REG_HDDEVSEL, 0x02); // nIEN bits
delay(10); // 10 uS delay
while( (ataReadByte(ATA_REG_CMDSTATUS1) & 0xC0) != 0x40 ); // Wait for DRDY and not BSY
return ataReadByte(ATA_REG_CMDSTATUS1) + ataReadByte(ATA_REG_ERROR);
}
/*
unsigned char ATA_Idle(unsigned char Drive)
{
WriteBYTE(CMD, 6, 0xA0 + (Drive ? 0x10:0x00)); // Select drive
WriteBYTE(CMD,7, 0xE1);
while ((ReadBYTE(CMD,7) & 0xC0)!=0x40); // Wait for DRDY & NOT BUSY
// Return the error register...
return ReadBYTE(CMD, 1);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -