IDE knowledge anyone?

Oliver Lehmann lehmann at ans-netz.de
Sun Dec 6 14:57:49 CST 2015


Hi,

I've built a Harddisk-Controller-Emulator for my system which accesses
a IDE (PATA) harddisk with an ATMega in PIO mode. It works like a charm
except for one WD harddisk. The harddisk itself works fine with MS-DOS
6.22 and FreeBSD but refuses to work with my ATMega.

On reading or writing a sector, right after the command is issued, the
error bit is set in the status register, and the error register indicates
an ABRT.

# ABRT:
# indicates the requested  command has been aborted  due to a
# drive status error (such as not ready or write fault) or because
# the command is invalid.

Right after power up and after the disk got ready, I issue the IDENTIFY
command and read the data back which works perfectly. After that I
read sector 0 and this fails.

I use LBA since the harddisk states that is supportes LBA. Nevertheless
I also tried accessing the harddisk with CHS mode and got the same error.

I tested other harddisks which support either CHS+LBA or CHS only. All
of them work perfectly.



What happens after powerup to read block 0 of the disk in LBA mode:

- Setup AVR ports and so on
- wait until RDY gets high
- wait until BSY gets low
- issue a Drive/Head register Command with value 0
- wait until BSY gets low
- issue a Command Register Command with value 0xEC (identify device)
- *read data*
- process and print out data
- wait until BSY gets low
- issue a Sector Count register Command with value 0
- issue a Sector Number register Command with value 0
- issue a Cylinder Low register Command with value 0
- issue a Cylinder High register Command with value 0
- issue a Drive/Head register Command with 0 + 0xE0 (LBA, Drive 0)
- issue a Command Register Command with value 0x20 (Read Sector)
- *read data*


*read data*:

- wait until BSY gets low
- check ERR bit in the Status register <- set on cmd 0x20 here
- wait until DRQ gets high
- issue a Data register Command with no data
- put /RD on low
- read 512 bytes of data
- put /RD on high
- check ERR bit in the Status register

Issuing a Command works always like setting /CS0, /CS1, /DA0, /DA1,
/DA2 to low, and then set the needed signals to high so the desired
command is indicated.
When data has to be transfered with this command, the lower 8 bits
are put then onto the port, /WR is set to low afterwards, 3 nop()
are done and /WR is set back to high.

Does anyone see an error what could make the drive behave like I said?

- ATA IDENTIFY works, and the drives data can be read
- after a read or write sector command is issued, the status register
directly goes 0xd0 (busy) and with the 2nd fetch 0x59 (not busy, drq
set, err set)

Regards, Oliver


More information about the cctech mailing list