FAT16 IDE Interface
SPI-IDE Interface prototype

This project was created to provide a simple command-driven interface to an IDE device that supports the FAT16 file structure. I specifically had Compact Flash (CF) media in mind as it can be powered from 5v and accessed as an IDE device. By using the FAT16 file structure, I can move the CF media between this adapter and a PC using a readily available USB flash memory reader. In this way, I can easily move program and data files between the HOST system and a PC for easy processing and storage.
A User Manual and support files are available here ->FAT16 IDE
Communication with the host is through a standard SPI interface. The design could be easily reconfigured to provide RS-232 or parallel interfaces as well.
The FAT16 driver supports 16 open files at a time. Files can be opened for READ, WRITE, or APPEND. Data can be read sequentially or you can set the file pointer to absolute or relative locations within the file. You pass the amount of bytes to read or write with each instruction.
File names are limited to the DOS 8.3 naming conventions. When moving through a directory tree, you can only move one level at a time. The exception is you can move to the ROOT directory at any time by using the "/" parameter. To move back one level, you use the ".." parameter. You can rename files, directories, and the volume label.
The HIDDEN and SYSTEM attributes are ignored in this implimetation. They will be maintained if already set by another source. The READ ONLY attribute is implimented and will prevent a file or directory from being erased or modified. Use the PROTECT and UNPROTECT commands to change this attribute. The ERASE ALL command will erase all files and empty directories in the current directory INCLUDING those marked READ ONLY. Therefore, this command must be used carefully.
The onboard DS1302 provides a real-time clock for date stamping of files. You can set and retrieve the current date and time from the HOST. If you do not install the DS1302, the firmware will return a default value, or the value you enter using the Set date/time function.
The FORMAT command will format the device with 1 partition using one FAT table. A maximum size of 2GB is supported. The interface cannot read secondary partions if they exist on the device. You may put two devices in the IDE connector and use the MASTER/SLAVE jumpers to have two drives available. However, only one drive can be accessed at a time. You need to re-initialize the interface to switch drives. Lastly, there is also support for RAW sector access for those not interested in using the FAT16 support. You may read and write 512-byte blocks to any sector on the drive. Care must be taken with FAT16-formatted drives if RAW commands are used or the file structure may become corrupt and unaccessible.
Here are the commands used to access the media from the Host:
HEX Command 00 reserved (null character) 01-1F reserved for returned error codes C0 Close all files C1 list directory C2 make directory C3 change directory C4 erase file/directory C5 erase all files and empty directories in current directory C6 protect file (read only attribute) C7 unprotect file (read only attribute) C8 rename file/directory/vol label C9 open File CA Read File CB Write File CC Set pointer CD Get pointer CE Close File CF Test if File Exists D0 File Size D1 Read Sector (Direct access mode) D2 Write Sector (Direct access mode) E0 list date/time E1 set date/time E2 get rtc reg F0 list volume label F1 list free space F2 format drive F3 list drive info F4 Mount drive (and Initialize FAT file System)The SPI communications channel is configures as a slave device. The Slave requires a minimum of 1.75uS to complete each SPI transaction. Read the status to ensure the slave is ready for your request. The host accesses the slave using these routines:
IDEStat - Returns the current status of the SPI Slave device SendIDECmd - Sends a 1-byte command to the slave SendIDE - sends 1 data byte to the slave RxIDE - gets 1 byte of data from the slaveThe IDEStat routine returns the status back to the Host using 1 byte:
Bit 7 - Ready for Command if 1 Bit 6 - Data Ready to send to the Host when 1 Bit 5 - Ready to receive data from the host when 0 bit 4-0 contain a binary error code. These are the error codes: 00000 - 00 - No Error 00001 - 01 - ATA init error 00010 - 02 - missing file name 00011 - 03 - Format error 00100 - 04 - File not found 00101 - 05 - Read Only File 00110 - 06 - invalid file type/open error 00111 - 07 - unable to erase all files 01000 - 08 - file not open 01001 - 09 - file already open in another handle 01010 - 0A - write protected 01011 - 0B - disk full 01100 - 0C - root directory full 01101 - 0D - invalid command 01110 - 0E - Handle in use 01111 - 0F - read past EOF 10000 - 10 - File too large > 2^32 10001 - 11 - Cluster size too big
Here are the 65C02/65816 routines:
SPIPort = $01 ; bit address of Slave on SPI slave select register
;
; Send Command to IDE
;
SendIDECmd pha
SendIDECmd1 jsr IdeStat
and #$A0
cmp #$80
bne SendIDeCmd1
bra SendIde1
;
; Send data (in A) to IDE Slave
;
SendIDE pha
SendIDE0 jsr IdeStat ; get status
and #$20 ; IDE ready for command and ready to receive data
bne SendIDE0 ; not ready, check status again
SendIDE1 lda #SPIPort ;
trb SPISSR ; select device
lda #$01 ; send data
sta spidr ;
SendIDE4 lda SPISR
bpl SendIDE4 ; wait for tx to end
nop
nop
nop
nop ; wait for SPI to be ready
lda spidr ; clr flags
pla ; send data byte
sta spidr ; start shift
SendIDE5 lda SPISR
bpl SendIDE5 ; wait for tx to end
lda spidr ; clr SPI flag
lda #SPIPort ;
tsb SPISSR ; Deselect device
rts
;
; Get Char from IDE
;
RxIde jsr IdeStat
and #$40 ; IDE data ready to send
beq RxIDE ; not ready, check status again
lda #SPIPort ;
trb SPISSR ; select device
lda #$03 ; send data
sta spidr ;
RxIDE4 lda SPISR
bpl RxIDE4 ; wait for tx to end
nop
nop
nop
nop ; wait for SPI to be ready
lda spidr ; clr flags
lda #$00 ; send null
sta spidr ; start shift
RXIDE5 lda SPISR
bpl RxIDE5 ; wait for tx to end
lda spidr ; get received data
pha ; save it
lda #SPIPort ;
tsb SPISSR ; Deselect device
pla ; restore data
rts
;
; Read IDE status
;
IdeStat lda #SPIPort ;
trb SPISSR ; select device
lda spidr ; clr flags
lda #$02 ; get status
sta spidr ;
IdeStat1 lda SPISR
bpl IdeStat1 ; wait for tx to end
nop
nop
nop
nop ; wait for SPI to be ready
lda spidr ; clr flags
lda #$00 ; null
sta spidr ; start shift
IdeStat2 lda SPISR
bpl IdeStat2 ; wait for tx to end
lda spidr ; get STATUS
pha
lda #SPIPort ;
tsb SPISSR ; Deselect device
pla ; restore data
rts
Here is a conceptual picture of the production board. It is very simple.
Here is the schematic:

Here is the PCB trace layout:

Here is the parts list:
Part Description Digikey Part #
-------------------------------------------------
C1 .1uF ceramic cap BC1160CT-ND
IC1 Atmel ATMega324P-20PU ATMEGA324P-20PU-ND
J1 SPI Port 2x5 header * Note 1
J2 IDE port 2x20 header * Note 1
J4 Host +5v 1x2 header * Note 2
OSC-1 20.0 MHz TTL Osc X964-ND
Jumper jumper block S9000-ND
for J4,J5,J7 if needed
(Optional components - see text)
B1 3V CR2032 P189-ND
C2 220uF Electrolytic Cap 493-1492-ND
C3 220uF Electrolytic Cap 493-1492-ND
IC2 DS1302 Real Time Clock DS1302+-ND
IC3 LM7805 5v Regualtor 497-1443-5-ND
J3 Ext +5v * Note 3
J5 Socket +5v 1x2 header * Note 2
J6 Ext 9-12v * Note 3
J7 Host 9-12v 1x2 header * Note 2
LED1 Red T1-3/4 Led with 516-1339-ND
internal current-limiting resistor
X1 32.768 khz crystal 300-8301-ND
Battery holder BH32T-C-ND
Note 1 - order one 1SAM1028-36-ND for J1 and J2
break off appropriate number if pins for each
Note 2 - order one TSW-106-07-L-S-ND for J4,J5, and J6
break into three 1x2 headers.
Note 3 - solder wire to the pads from external connectors
All parts are available from Digikey.com
A printed circuit board and programmed ATmega324P
are available from the author for $32 plus shipping.
Inexpensive IDE-CF adapters are available from places like
Amazon, Ebay, and geeks.com.
| Home |