 for my 63B03 microcontroller system. This info is, <<<<<

>>>>> as far as I know still true as it stands here. I   <<<<<

>>>>> have in fact based the pofoide interface directly  <<<<<

>>>>> on this info.                                      <<<<<

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

> When you read this you will find out that I have slightly 

> changed the way I connected the 8255 to the IDE bus. I use

> port C for the control signals in th pofoide interface, port A

> in this description. The change is minor; It gives me the 

> option to use the 8255's bit set/reset commands to speed up

> the interface. 



How to connect an IDE disk to a microcontroller using an 8255

=============================================================





Introduction

============



Some time ago I have dropped that I had connected an IDE harddisk

to one of my microcontrollers. This has provoced a response that

I had not forseen. Since that day I have received some one to two

e-mails a day requesting more details about what I had done. At

first I have mailed a more or less cryptic decription of my

interface to some of the requesters. That only resulted in more

e-mail asking for more details. As it seems some people out there

are really interested in how my contraption is made. In this

description I will attempt to satify the information-hunger of

all you out there who's appetite I seem to have awakened.



This interface first came to my mind when I re-read some old, old

computer magazines. In one of them, the German magazine called

C't there was a short description of how and IDE interface is put

together. This is in the November issue of 1990. The article

describes an IDE interface for both the PC-XT(!) and the PC-AT.

The circuit diagrams of the article indcate that the hardware of

an IDE interface is in fact very simple. It is essentially a data

bus extension from the PC-AT bus to an IDE device. For a PC the

hardware comes down to some bus buffers and some decoding. When a

disk is connected as an IDE device the PC-AT still 'sees' the

old-type control registers of the ancient MFM disk controller. In

the article the entire interface is implemented using simple TTL

chips. The main problem in a PC seems to be how to keep the

harddisk interface and the floppy interface from colliding on

some register addresses. If the IDE interface is implemented

based on some controller system this is of course no problem.



>From a controller point of view an IDE interface could be

described as a set of I/O ports. The IDE interface has a 8/16

bits I/O bus, two /CS lines, a /WR and /RD line, three address

bits and one interrupt. In this description I assume the most

traditional IDE interface. In later IDE interfaces a series of

nice so-called PIO modes where added. These PIO modes add things

like a ready line, DMA facilities and higher speed data

transfers. As you read on you will understand that I only use the

so-called PIO mode 0. This is the slowest communication modus on

an IDE bus. It is also the easiest one to implement. The data bus

on an IDE interface is used mostly for 8-bits transfers. Only the

real disk data reads and writes use the 16-bits bus in full

width. You COULD even implement an IDE interface with an 8-bits

only data bus. That would mean that you use only half the disk

capacity (the lower bytes of the 16-bits-wide bus) but that

should work.



When scanning the net I did find an implementation of an IDE

interface for 8-bit controllers. This interface was for a (hope I

have this correct..) COCO bus. It was implemented in TTL, just

like the magazine's interface. The main idea was that whenever a

(16-bits) word was read from the IDE bus the upper 8 bits where

stored in a latch. The controller could retrieve them from the

latch later. Writing to the IDE bus was implemented in the same

manner. The IDE bus read/write cycles where in fact simple bus

read and write cycles. At first I was about to copy this design.

When thinking about it I thought that this TTL design was too

complex for what I wanted to do. You need quite some TTL to

implement a 16-bits read/write I/O port in TTL on an 8-bits

controller.





Hardware description

====================



When implementing a 16-bits I/O port all you need is a

bidirectional I/O port and some control bits to generate the /RD,

/WR etc... That is when the 8255 came in view. An 8255 has 3

8-bits I/O ports. It can be switched from output to input and

back under software control. I used 2 of the 8-bits I/O ports for

the data path and use port to generate the IDE control signals.

The 74HC04 came into the design later. Once I had the controller

and the 8255 strapped together with the IDE connector and a disk

I found out that the 8255 has a nasty trait. Whenever you switch

the I/O modus of the chip it resets ALL its memory bits. That

includes ALL output signals too. For the data bus that is not so

much of a problem. The control signals get a real shake when this

happens. In particular: The /RESET line of the interface is

activated. That makes all control of a disk on this interface

impossible (the disk gets a reset at all kinds of odd

moments...). I have solved this by simply inverting all the

control signals from the 8255 to the IDE bus. When the modus of

the 8255 is switched all outputs of the chip go to '0'. That

means that all the (low-active) control signals are made inactive

by the inversion. That is -in fact- the state where I have them

already when I'm about to change the 8255's modus.



At this point I would like to present a nice circuit diagram to

show what the contraption I have made looks like. Unfortunately I

know of no easy way to do that. This beautiful net is a marvel

when it comes down to transporting text, graphics is another

matter. A GIF picture would do the work; I do not have any means

to produce one. Some schematics drawing package could give a good

picture; I have no schematics package and I am not sure what

package would be universal enough to be usable by everyone. So I

am restricted to a more or less cryptic ASCII description of the

hardware. Please, the cryptology is out of need, not out of my

liking. Well here it comes:



1) The IDE bus pin connections themselves:

   ---------------------------------------



The IDE connector itself is a 40-pins two-row connector:



    1                  39    odd-numbered pins

    ....................

    ....................

    2                  40    even-numbered pins



In an IDE bus this connector is used as follows:



pin no:      name:     function:

---------   -------    ---------



1            /RESET    Al low signal level on this pin will reset

                       all connected devices



2,19,22      GND       ground, interconnect them all and tie to

24,26,30               controller's ground signal

40



3,5,7,9,11   D7..D0    low data bus, 3=D7 .. 17=D0. This part of

13,15,17               the bus is used for the command and

                       parameter transfer. It is also used for

                       the low byte in 16-bits data transfers.



4,6,8,10     D8..D15   high data bus, 4=D8 .. 18=D15. This part

12,14,16,18            of the bus is used only for the 16-bits

                       data transfer.



20           -         This pin is usually missing. It is used to

                       prevent mis-connecting the IDE cable.



21 and       /IOREADY  I do not use or connect to this pin. It is

27                     there to slow down a controller when it is

                       going too fast for the bus. I do not have

                       that problem...



23           /WR       Write strobe of the bus.



25           /RD       Read strobe of the bus.



28           ALE       Some relic from the XT time. I do not use

                       it, and I'm not the only one...



31           IRQ       Interrupt output from the IDE devices. At

                       this moment I do not use it. This pin

                       could be connected to a controller to

                       generate interrupts when a command is

                       finished. I have an inverter ready for

                       this signal (I need a /IRQ for my

                       controller, an IRQ is of no use to me..)



32           IO16      Used in an AT interface to enable the

                       upper data bus drivers. I do not use this

                       signal. It is redundant anyway, the ATA-3

                       definition has scrapped it.



34           /PDIAG    Master/slave interface on the IDE bus

                       itself. Leave it alone or suffer

                       master/slave communications problems. Not

                       used (or connected to ANYTHING) by me.



35           A0        Addresses of the IDE bus. With these

33           A1        you can select which register of the IDE

36           A2        devices you want to communicate.



37           /CS0      The two /CS signals of the IDE bus. Used

38           /CS1      in combination with the A0 .. A2 to select

                       the register on the IDE device to

                       communicate with.



39           /ACT      A low level on this pin indicates that the

                       IDE device is busy. I have connected a LED

                       on this pin. The real busy signal for the

                       controller I get from the IDE status

                       register.



Input/Output status of these signals:

-------------------------------------



The signals:

A0, A1, A2, /CS0, /CS1, /WR, /RD and /RESET are always outputs

from the controller to the IDE bus.



The signals:

IRQ and /ACT are always outputs from the IDE bus to the

controller (IRQ can be tri-stated by the IDE device when two

devices are connected to the IDE bus.) /ACT can drive a LED (with

resistor of course).



The signals:

D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14,

D15 are bi-directional. They are output from the controller to

the IDE bus when writing, output from the IDE device to the

controller when reading information.



2) The 8255 <-> controller

   -----------------------



The 8255 is connected to the controller by means of its 8-bit

data bus, the A0 and A1 lines and the /CS, /WR and /RD lines. I

can not give that much info about this. If in doubt: consult the

8255 data sheet. This part depends as much on the controller you

use as anything else. I have the 8255 connected to my controller

(HD63B03R1CP, a Hitachi 6803-derivate..) as an I/O port. Perhaps

some of you have seen my previous e-mails asking for the pinout

of the HD63B03R1CP (52-pins PLCC) chip, well I did find it (Some

department of my work had an old Hitachi databook, voila the

pinout was there). My address decoding puts the 8255 on address

0500H to 0503H in the controller's memory map. That may help if

you decide to try to make sense of my software listing. On this

point you are on your own as to the how to connect a 8255 to your

controller.



3) 8255 <-> IDE connector

   ----------------------



I have used the 8255's port A to generate the IDE bus control

signals. Some of these control signals pass through an inverter

before I connected them to the IDE connector itself. All of these

signals are always used as output from the 8255 to the IDE bus.

When a control signal is inverted the 8255 pin is connected to

one of the inputs of the 74HC04 and the (corresponding) output of

the 74HC04 is connected to the IDE bus connector.



The ports B and C are used as the 16-bits data bus. There are no

special things in this, it's just a simple interconnection of the

8255 I/O pins to the D0..D15 pins of the IDE connector.



I have connected this as follows:

---------------------------------



PA.7  --> inverter --> IDE bus /RESET

PA.6  --> inverter --> IDE bus /RD

PA.5  --> inverter --> IDE bus /WR

PA.4  --> inverter --> IDE bus /CS1

PA.3  --> inverter --> IDE bus /CS0

PA.2  -->              IDE bus A2

PA.1  -->              IDE bus A1

PA.0  -->              IDE bus A0



PB.7 <--> IDE bus D7

PB.6 <--> IDE bus D6

PB.5 <--> IDE bus D5

PB.4 <--> IDE bus D4

PB.3 <--> IDE bus D3

PB.2 <--> IDE bus D2

PB.1 <--> IDE bus D1

PB.0 <--> IDE bus D0



PC.7 <--> IDE bus D15

PC.6 <--> IDE bus D14

PC.5 <--> IDE bus D13

PC.4 <--> IDE bus D12

PC.3 <--> IDE bus D11

PC.2 <--> IDE bus D10

PC.1 <--> IDE bus D9

PC.0 <--> IDE bus D8



I have put a 10 KOhm pull-down resistor from the IDE bus IRQ to

ground. The IDE IRQ signal is also connected to the input of the

(one-remaining) inverter. The output of the inverter is connected

to the controller's /IRQ input. As you can see, I do have the

hardware for interrupts here, I do not use it. I tried to use it,

but got unexplained errors (I probably did something wrong, I

have not yet found what)..



                   |\

IDE IRQ o-----+----+ >o--------o CPU's /IRQ

              |    |/

             +++

             | |

             | | 10 KOhm

             +++

              |

              |

             -+- GND

             ///



The IDE /ACT signal is connected to a 330 Ohm resistor, the other

end of the resistor is connected to a LED, the other end of the

LED is connected to the +5 Volts. This gives a nice LED

indication of when I'm using the disk. This is -as far as I know-

the same hardware a PC uses to produce the disk busy LED you may

find on the front of a PC box.



                 330 Ohm

               +-------+     LED

IDE /ACT o-----+       +------|<-----o +5 Volts

               +-------+



So much about the hardware of the IDE interface. I hope that is

all clear now. If I have been less than clear, please ask. If I

have made mistakes, please complain (I said complain, NOT FLAME!!!).





IDE read/write and register description

=======================================



The IDE device appears to the IDE bus as a set of regsiters. The

register selection is done with the /CS0, CS1 and A0, A1, A2

lines. Reading/writing is done with the /RD and /WR signals. I

have used the 8255 port A signals to make read/write cycles on

the IDE bus. What I do is the following:



read cycle:

-----------



1) put the port B and C of the 8255 in input modus.



2) set an address and /CS0 and /CS1 signal on the port A of the

   8255.



3) activate the /RD of the IDE bus by setting the equivalent bit

   in the port A of the 8255.



4) read the data from port B (and C) of the 8255.



5) deactivate the /RD signal on the IDE bus by resetting the

   equivalent bit of port A of the 8255.



write cycle:

-----------



1) put the port B and C of the 8255 in output modus.



2) set an address and /CS0 and /CS1 signal on the port A of the

   8255.



3) set a data word (or byte) on port B (and C) of the 8255.



4) activate the /WR of the IDE bus by setting the equivalent bit

   in the port A of the 8255.



5) deactivate the /WR signal on the IDE bus by resetting the

   equivalent bit of port A of the 8255.



The only difference between 8 bits and 16 bits transfers is the

following:



- In an 8-bit transfer I use only the port B of the 8255 for data

  transfer. When writing I put data only on the lower byte of the

  IDE bus; the upper byte is ignored anyway by the IDE device.

  When reading I read only port B of the 8255; I never even

  bother to look at the upper byte.



- In an 16-bit transfer I read/write to both the upper and the

  lower byte of the IDE bus; thus using both port B and port C.



The IDE device appears as the following registers:

--------------------------------------------------



/CS0=0, /CS1=1, A2=A1=A0=0: data I/O register (16-bits)

This is the data I/O register. This is in fact the only 16-bits

wide register of the entire IDE interface. It is used for all data

block transfers from and to the IDE device.



/CS0=0, /CS1=1, A2..A0=001B: This is the error information

register when read; the write precompensation register when

written. I have never bothered with the write precompensation at

all, I only read this register when an error is indicated in the

IDE status register (see below for the IDE status register).



/CS0=0, /CS1=1, A2..A0=010B: Sector counter register. This

register could be used to make multi-sector transfers. You'd have

to write the number of sectors to transfer in this register. I

use one-sector only transfers; So I'll only write 01H into this

register. I do use this register to pass the parameter the

timeout for idle modus command via this register.



/CS0=0, /CS1=1, A2..A0=011B: Start sector register. This register

holds the start sector of the current track to start reading/

writing to. For each transfer I write the start sector in this

register. For some fancy reason the sector count starts at 1 and

runs up to 256, so writing 00H results in sector number 256. Why

that is done is a mystery to me, all other counting in the IDE

interface starts at 0.....



/CS0=0, /CS1=1, A2..A0=100B: Low byte of the cylinder number.

This register holds low byte of the cylinder number for a disk

transfer.



/CS0=0, /CS1=1, A2..A0=101B: High two bits of the cylinder

number. The traditional IDE interface allows only cylinder

numbers in the range 0..1023. This register gets the two upper

bits of this number. I write the cylinder number's upper two bits

into this register before each transfer.



/CS0=0, /CS1=1, A2..A0=110B: Head and device select register. The

bits 3..0 of this register hold the head number (0..15) for a

transfer. The bit 4 is to be written 0 for access to the IDE

master device, 1 for access to the IDE slave device. The bits

7..5 are fixed at 101B in the traditional interface.



/CS0=0, /CS1=1, A2..A0=111B: command/status register. When

written the IDE device regards the data you write to this

register as a command. When read you get the status of the IDE

device. Reading his register also clears any interrupts from the

IDE device to the controller.



/CS0=1, /CS1=0, A2..A0=110B: 2nd status register/interrupt and

reset register. When read this register gives you the same status

byte as the primary (/CS0=0, /CS1=1, A2..A0=111B) status

register. The only difference is that reading this register does

not clear the interrupt from the IDE device when read. When

written you can enable/disable the interrupts the IDE device

generates; Also you can give a software reset to the IDE device.



/CS0=1, /CS1=0, A2..A0=111B: active status of the IDE device. In

this register (read-only) you can find out if the IDE master or

slave is currently active and find the currently selected head

number. In a PC environment you can also find out if the floppy

is currently in the drive. I have not used this register yet.



Some of these registers have bitwise meanings. I'll elaborate on

that here:



head and device register:

-------------------------

A write register that sets the master/slave selection and the

head number.



bits 3..0: head number [0..15]

bit  4   : master/slave select: 0=master,1=slave

bits 7..5: fixed at 101B. This is in fact the bytes/sector

           coding. In old (MFM) controllers you could specify if

           you wanted 128,256,512 or 1024 bytes/sector. In the

           IDE world only 512 bytes/sector is supported. This bit

           pattern is a relic from the MFM controllers age. The

           bit 6 of this pattern could in fact be used to access

           a disk in LBA modus.



Status register:

----------------

Both the primary and secondary status register use the same bit

coding. The register is a read register.



bit 0    : error bit. If this bit is set then an error has

           occurred while executing the latest command. The error

           status itself is to be found in the error register.

bit 1    : index pulse. Each revolution of the disk this bit is

           pulsed to '1' once. I have never looked at this bit, I

           do not even know if that really happens.

bit 2    : ECC bit. if this bit is set then an ECC correction on

           the data was executed. I ignore this bit.

bit 3    : DRQ bit. If this bit is set then the disk either wants

           data (disk write) or has data for you (disk read).

bit 4    : SKC bit. Indicates that a seek has been executed with

           success. I ignore this bit.

bit 5    : WFT bit. indicates a write error has happened. I do

           not know what to do with this bit here and now. I've

           never seen it go active.

bit 6    : RDY bit. indicates that the disk has finished its

           power-up. Wait for this bit to be active before doing

           anything (execpt reset) with the disk. I once ignored

           this bit and was rewarded with a completely unusable

           disk.

bit 7    : BSY bit. This bit is set when the disk is doing

           something for you. You have to wait for this bit to

           clear before you can start giving orders to the disk.



interrupt and reset register:

-----------------------------

This register has only two bits that do something (that I know

of). It is a write register.



bit 1    : IRQ enable. If this bit is '0' the disk will give and

           IRQ when it has finished executing a command. When it

           is '1' the disk will not generate interrupts.

bit 2    : RESET bit. If you pulse this bit to '1' the disk will

           execute a software reset. The bit is normally '0'. I

           do not use it because I have full software control of

           the hardware /RESET line.



Active status register:

-----------------------

This is a read register. I have -up till now- ignored this

register. I have only one IDE device (a disk) on my contraption.



bit 0    : master active. If this bit is set then the master IDE

           device is active.

bit 1    : slave active. If this bit is set then the slave IDE

           device is active.

bits 5..2: complement of the currently active disk head.

bit 6    : write bit. This bit is set when the device is writing.

bit 7    : in a PC environment this bit indicates if a floppy is

           present in the floppy drive. Here it has no meaning.



error register:

---------------

The error register indicates what went wrong when a command

execution results in an error. The fact that an error has

occurred is indicated in the status register, the explanation is

given in the error register. This is a read register.



bit 0    : AMNF bit. Indicates that an address mark was not

           found. What this means I not sure of. I have never

           seen this happen.

bit 1    : TK0NF bit. When this bit is set the drive was not able

           to find track 0 of the device. I think you will have

           to throw away the disk if this happens.

bit 2    : ABRT bit. This bit is set when you have given an

           indecent command to the disk. Mostly wrong parameters

           (wrong head number etc..) cause the disk to respond

           with error flag in the status bit set and the ABRT bit

           set. I have gotten this error a lot when I tried to

           run the disk with interrupts. Something MUST have been

           wrong with my interface program. I have not (yet)

           found what.

bit 3    : MCR bit. indicated that a media change was requested.

           What that means I do not know. I've ignored this bit

           till now.

bit 4    : IDNF bit. Means that a sector ID was not found. I have

           never seen this happen, I guess it means that you've

           requested a sector that is not there.

bit 5    : MC bit. Indicates that the media has been changed. I

           ignore this bit.

bit 6    : UNC bit. Indicates that an uncorrectable data error

           happened. Some read or write errors could provoce

           this. I have never seen it happen.

bit 7    : reserved.



Note: I have these registers descriptions from two sources:



1) The C't magazine I mentioned before. It's in German, not very

   complete (the error register description is missing) and very

   old. It does have a hardware description of and IDE interface

   however....



2) The document X3T10/2008D: Information Technology-

   AT Attachment-3 Interface (ATA-3), Working draft.

   This latter document gives an exhaustive overview of the IDE

   interface. It states more details of the IDE interface than I

   can ever hope to include in this short description. It does

   however have one disadvantage: it's BIG. I found the document

   on the net (on the Western Digital homepage) in the form of an

   .exe file. When you run this file on a PC you are rewarded

