|
|
|
D7-0 or D15-0 |
bidirectional |
Data bus |
|
A2-0 |
input |
Address bus |
|
/RESET |
input |
Device reset |
|
/CS0 |
input |
chip select |
|
/DIOW |
input |
IO write |
|
/DIOR |
input |
IO read |
All ATA operations are performed by reading or writing eight registers. These are mainly the command, cylinder, head, drive... and data register. For example, to set the drive to sleep mode (power down spindle motor), write the drive number (master or slave) to the C/D/H register (6) and the SLEEP opcode (99) to register 7.
As data transfers, only entire sectors (=512 bytes) can be read or written. A write operation is performed by writing the drive number, sector number and WRITE SECTOR(S) opcode to the command... registers and writing 256 16 bit words to the data register. While the control registers are only 8 bit wide, the data register is 16 bit wide. There is a SET FEATURE command to switch to 8 bit data transfers, but with modern drives, this doesn's seem to work (no wonder, as the manufacturers implement high performance UDMAxxx modes). CF cards do support this, see below. You have to check the status flags (busy, error) periodically, eg after a read command to wait until the data is ready.
The Identify Drive command (EC) is especially useful. You can use this during your experiments as this is the only way of getting meaningful data from the drive without having written it before. It's also a nice way to make sure everything works - after power-up, the microcontroller of the Alya board first issues an identify drive command and displays the model number of harddisk and CF card in the display. You can also get the number of sectors from the drive, which might be interesting for programming. Nowadays, harddisk sectors are addressed using the LBA number, which is simply the sector number starting from 0 to the maximum sector number. This linear addressing scheme is much easier than the older cylinder/head/sector (CHS) addressing.
Compact Flash (CF) cards behave more or less like harddisks. They have the same interface, are organized in sectors and the contents are the same (partition table, FAT16 partition...) as common harddisks in a PC with a M$ operating system.
The compact flash interface (download spec from www.compactflash.org) has two main operating modes: The first is the PC-CARD (PCMCIA) compatible mode. There are passive adaptors letting you plug a CF card into a laptop PC-CARD slot. The second in the "true IDE mode" in which the CF card behaves exactly like an ATA device. This makes it possible to connect a CF card directly to your computers' IDE interface (see picture). This is not very practical, though, as neither the interface nor the operating system are made for hot-plugging the memory card.
Anyway, by selecting the true IDE mode (by tying /ATA SEL low), you simply use the same control scheme like for an ATA drive. There are two main differences:
1. CF cards do support 8 bit data transfers. This saves eight bidirectional data pins and makes the interface much more compact (14 pins, not counting reset), which is important for small processors like the PIC devices.
2. CF cards work with 3,3 and 5V. In 5V mode, the levels are not TTL compatible (no problem for PICs though). Read the spec! I evaded this problem by operating the CF card with 3,3V (no problem as the FPGA is also a 3,3V device).
If you need to store a large amount of data, compact flash cards or harddisks are an option. The capacity ranges from 16M (CF, DM100) to currently 75G (harddisk, DM 1350).
Most people I spoke to thought the harddisk interface would be pretty complex and interfacing to it some kind of wizardry. It isn't. Actually it's that simple that you'll soon be asking yourself what gimmicks you could build with it!
When you decide to use the ATA interface, you can choose between CF cards and harddisks. CF cards are more compact, need less power when running and have an (optional) 8 bit data port. They are limited in size, though. Harddisks have a good capacity/price ratio and the 2,5" ones (more expensive) are also quiet compact. 3,5" drives need 5 and 12V, while 2,5" drives run with 5V (usually max. 1A during startup and 500mA operating). The nice thing is that you can use (almost) the same interface for accessing a 35GB harddisk as for an 8 MB CF card. You'll need some kind of power management, as both CF and HD need too much power when active. You could use a buffer memory and periodically switch the drive on, copy the contents of the buffer to the disk and switch it off again. A harddisk will need 5-10s before it's ready, my 32MB CF card is ready after about 3s.
The interface itself is simple - you either connect the signals directly to your system's bus or if there isn't one (like when using a PIC), connect them to the port pins. Generating read and write cycles by pulling /cs and /rd or /wr low is easy. You can even use all but the /cs lines for other functions - like for interfacing to an LCD module or to another drive.
In a simple data logger application, the WRITE SECTOR(S) command might be the only ATA command you'll need. A serious problem when reading or writing data is that you always have 512 bytes - especially with the almost ram-less PIC devices. Perhaps a serial EEPROM could be used as low power (and low pin count) buffer memory.
An unformatted drive is basically a large array of sectors you can read or write. To store files and directory structures on a harddisk, you need a file system. On DOS based machines, FAT12 is used for floppy disks (or for small (8MB) CF cards), FAT16 for partitions <2G and FAT32 for larger (several TB) drives. A drive can consist of several (different) partitions. A very good introduction in FAT file systems was printed (in German) in c't 6/2000.
As I wrote above, Alya does not interpret the structure of the CF card, but simply copies the sectors 0..62975 of the CF card to sectors n*65536..n*65536+62975 of the harddisk (n=slot number). Unfortunately, I have to decode the file system because the camera writes its pictures using FAT16 format. I'm decoding the FAT16 structures when reading the harddisk via the parallel port.
For other applications (like a simple data logger), you could get around this. If you only need one linear area for your data, you could do the following:
On a non-fragmented drive, your file will occupy sectors a...b in an increasing order. Find out (using a disk editor) where sector a is located and you can overwrite this file with your microcontroller system, simply by writing your data to sectors a...b. After re-installing the drive in your computer, you can read the dummy file (dummy.txt) and get the data. Fortunately, there is no checksum of the data! You could also write a specific signature to the file and let the microcontroller find the first sector of it.
I have to admit that most of the explanations above are very superficial. It's just not possible to reduce a three-week-project into a few lines of text. But I hope it's still a starting point if you intend to use CF cards or harddisks in your design.
After almost four weeks holiday in south france, the Alya box was filled with 700 pictures from the digital camera. Extracting them worked at the first go and none of the pictures was corrupted. As the parallel port transfer is much faster than the camera's serial connection, I also use it for downloading images to the computer.
If I had too much time (...), I'd redesign the electronics to fit in a much more compact case. There is no reason why it should be much bigger than the harddisk itself. The prototype wasn't planned to fit together mechanically (and it didn't, consequently) because I didn't have the time for it. The power supply I got from the junk somewhere was huge and the LC display is not really necessary. A single button and a green LED would do it. Next time...