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