FAT16 IDE to HOST Adapter

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 slave
The 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				; 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
; 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				; 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
; 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				; 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
		lda	#SPIPort		;
		tsb	SPISSR			; Deselect device
		pla				; restore data

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. 

All info provided "as-is" and is Copyright 2020.