📄 ide.i
字号:
//#ifndef __IDE_H__
//#define __IDE_H__
//control bits of hard drive ('_' means active low)
//data bus of hard drive
//command block registers
//control block registers
void InitDrive(void);
void SetRegAddr(unsigned char reg);
unsigned int ReadRegister();
void WriteRegister(unsigned int val);
void WaitNBusy(unsigned char bReady);
void SetBusIn(void);
void SetBusOut(void);
unsigned char ReadSectorLBA(unsigned long lba,unsigned char *buffer);
//#endif //__IDE_H__
void SetBusIn(void)
{
//set up data bus as an input
DDRA = 0; //PORTA is an input
DDRC = 0; //PORTC is an input
PORTA = 0xff;
PORTC = 0xff;
delay_us(5);
}
void SetBusOut(void)
{
//set up data bus as an output
DDRA = 0xff; //PORTA is an output
DDRC = 0xff; //PORTC is an output
delay_us(5);
}
void InitDrive(void)
{
//set up data bus as an input
SetBusIn();
//set up control bus (output)
DDRB = 0xff; //PORTB is an output
PORTB = 0xe3; //negate all outputs
delay_us(5);
//send reset signal to drive
PORTB = 0x63; //assert reset bit
delay_ms(10); //wait 10 ms
PORTB = 0xe3; //negate reset bit
}
void SetRegAddr(unsigned char reg)
{
SetBusOut();
//output address of a command or control register
PORTB = (PORTB & 0x83) | (reg << 2);
}
unsigned int ReadRegister()
{
unsigned int val;
SetBusIn();
//asert read signal
PORTB.1 = 0;
delay_us(5);
//read date from bus
val = PINA;
val |= ((unsigned int) PINC) << 8;
//negate read signal
PORTB.1 = 1;
delay_us(5);
return val;
}
void WriteRegister(unsigned int val)
{
SetBusOut();
//asert write signal
PORTB.0 = 0;
delay_us(5);
//read date from bus
PORTA = val;
PORTC = (val >> 8);
//negate write signal
PORTB.0 = 1;
delay_us(5);
}
//wait for DRDY as well if (bReady == 1)
void WaitNBusy(unsigned char bReady)
{
unsigned char val, BSY = 1, DRDY = 0;
SetBusIn();
//set register address
SetRegAddr(0x0e);
do
{
//get status register
val = ReadRegister();
//extract bits from register
BSY = val >> 7;
DRDY = (val >> 6) & 1;
}
while(BSY || (bReady && !DRDY));
}
unsigned char ReadSectorLBA(unsigned long lba,
unsigned char *buffer)
{
unsigned char head, sector;
unsigned int cylinder;
unsigned char status;
unsigned int i, tmp;
//convert parse LBA address to load into registers
sector = (unsigned char) lba;
cylinder = (unsigned int) (lba >> 8);
head = (unsigned char) (lba >> 24);
/*printf("lba(lo) = %0x\r\n", lba);
printf("lba(hi) = %0x\r\n", lba >> 16);
printf("head = %0x\r\n", head);
printf("cylinder = %0x\r\n", cylinder);
printf("sector = %0x\r\n", sector);*/
//wait for device to be not busy
WaitNBusy(0);
//write drive/head register to select device 0
SetRegAddr(0x16);
WriteRegister(head | 0xe0);
//wait for device to be not busy and ready
WaitNBusy(1);
//write parameters of read sectors command
SetRegAddr(0x12);
WriteRegister(1);
SetRegAddr(0x13);
WriteRegister(sector);
SetRegAddr(0x14);
WriteRegister(cylinder);
SetRegAddr(0x15);
WriteRegister(cylinder >> 8);
//write read sectors command
SetRegAddr(0x17);
WriteRegister(0x20);
for(i = 0; i < 512; i = i + 2)
{
WaitNBusy(0);
SetRegAddr(0x17);
status = ReadRegister();
//check for error (ERR == 1)
if (status & 1)
return 0;
SetRegAddr(0x10);
tmp = ReadRegister();
//split data into 8-bit pieces
buffer[i] = tmp;
buffer[i+1] = tmp >> 8;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -