//************************************************************************************
//**  
//**  File name:     C:\Documents and Settings\Henry Bergin\Desktop\Flowcode 5 project files\Misc\SDcard\SD Project.c
//**  Title:         
//**  Description:   
//**  
//**  Generated by:  Flowcode v5.3.0.0
//**  Date:          Saturday, August 25, 2012 14:41:20
//**  Licence:       Professional
//**  Registered to: tackyattack
//**  Licence key:   K38B95
//**  
//**  
//**  http://www.matrixmultimedia.com
//**  
//************************************************************************************


#define MX_AVR

#define MX_USES_UINT8 1
#define MX_USES_SINT16 0
#define MX_USES_CHAR 0
#define MX_USES_FLOAT 0
#define MX_USES_SINT32 0
#define MX_USES_BOOL 1
#define MX_USES_UINT16 0
#define MX_USES_UINT32 0
//Defines for microcontroller
#define FC_CAL_AVR
#define MX_ADC
#define MX_ADC_TYPE_2
#define MX_ADC_BITS_10
#define MX_EE
#define MX_EE_SIZE 1024
#define MX_SPI_1
#define MX_SPI_1_MISO_PORT PORTB
#define MX_SPI_1_MISO_TRIS DDRB
#define MX_SPI_1_MISO_PIN 4
#define MX_SPI_1_MOSI_PORT PORTB
#define MX_SPI_1_MOSI_TRIS DDRB
#define MX_SPI_1_MOSI_PIN 3
#define MX_SPI_1_CLK_PORT PORTB
#define MX_SPI_1_CLK_TRIS DDRB
#define MX_SPI_1_CLK_PIN 5
#define MX_SPI_1_SS_PORT PORTB
#define MX_SPI_1_SS_TRIS DDRB
#define MX_SPI_1_SS_PIN 2
#define MX_UART_1
#define MX_UART_1_TX_PORT PORTD
#define MX_UART_1_TX_TRIS DDRD
#define MX_UART_1_TX_PIN 1
#define MX_UART_1_RX_PORT PORTD
#define MX_UART_1_RX_TRIS DDRD
#define MX_UART_1_RX_PIN 0
#define MX_UART_ID
#define MX_UART_UCSRC
#define MX_MI2C
#define MX_I2C_1
#define MX_I2C_1_SDA_PORT PORTC
#define MX_I2C_1_SDA_TRIS DDRC
#define MX_I2C_1_SDA_PIN 4
#define MX_I2C_1_SCL_PORT PORTC
#define MX_I2C_1_SCL_TRIS DDRC
#define MX_I2C_1_SCL_PIN 5
#define MX_PWM
#define MX_PWMTYPE 1
#define MX_PWM_CNT 6
#define MX_PWM_TMR0_CNT 2
#define MX_PWM_TMR1_CNT 2
#define MX_PWM_TMR2_CNT 2
#define MX_PWM_PSCA1
#define MX_PWM_PSCA8
#define MX_PWM_PSCA64
#define MX_PWM_PSCA256
#define MX_PWM_PSCA1024
#define MX_PWM_1_PORT PORTD
#define MX_PWM_1_TRIS DDRD
#define MX_PWM_1_PIN 6
#define MX_PWM_2_PORT PORTD
#define MX_PWM_2_TRIS DDRD
#define MX_PWM_2_PIN 5
#define MX_PWM_3_PORT PORTB
#define MX_PWM_3_TRIS DDRB
#define MX_PWM_3_PIN 1
#define MX_PWM_4_PORT PORTB
#define MX_PWM_4_TRIS DDRB
#define MX_PWM_4_PIN 2
#define MX_PWM_5_PORT PORTB
#define MX_PWM_5_TRIS DDRB
#define MX_PWM_5_PIN 3
#define MX_PWM_6_PORT PORTD
#define MX_PWM_6_TRIS DDRD
#define MX_PWM_6_PIN 3

//Functions
#define F_CPU 20000000UL
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\eeprom.h>
#include <avr\wdt.h>

//Configuration data
#pragma DATA 0x0, 0xdf
#pragma DATA 0x1, 0xff
#pragma DATA 0x2, 0xff

//Internal functions
#include "C:\Program Files\Flowcode(AVR)\v5\FCD\internals.c"

//Macro function declarations


//Variable declarations
#define FCV_FALSE (0)
#define FCV_TRUE (1)
volatile MX_UINT8 FCV_STATUS;




//FAT16(0): //Defines:

/**** Macro Substitutions ****
a = Unique Ref
b = SPI Channel
c = MOSI Pin
d = MOSI Port
e = MISO Pin
f = MISO Port
g = SCK Pin
h = SCK Port
i = CS Pin
j = CS Port
k = File Creation Time
l = File Creation Date
m = FAT System Type - 0=FAT16 Only / 1=FAT32 Only / 2=FAT16&32
******************************/


//Definitions for CS control line
#define FAT_2_MX_SPI_FAT_CS_PIN		2
#define FAT_2_MX_SPI_FAT_CS_PORT		portb
#define FAT_2_MX_SPI_FAT_CS_TRIS		trisb


//Definitions for SPI slot allocation
#ifndef	MX_SPI_REF1
	#define MX_SPI_REF1
	#define FAT_2_MX_SPI_UREF			1
	#define MX_SPI_CHANNEL_1		1
	#define MX_SPI_MOSI_PIN_1		-1
	#define MX_SPI_MOSI_PORT_1		port0
	#define MX_SPI_MOSI_TRIS_1		tris0
	#define MX_SPI_MISO_PIN_1		-1
	#define MX_SPI_MISO_PORT_1		port0
	#define MX_SPI_MISO_TRIS_1		tris0
	#define MX_SPI_SCK_PIN_1		-1
	#define MX_SPI_SCK_PORT_1		port0
	#define MX_SPI_SCK_TRIS_1		tris0
	#define MX_SPI_CS_PIN_1			0
	#define MX_SPI_CS_PORT_1		0
	#define MX_SPI_BMODE_1			1
	#define MX_SPI_PR_SCALE_1		4
	#define MX_SPI_PO_SCALE_1		1
	#define MX_SPI_INT_1			0
#else
 #ifndef	MX_SPI_REF2
	#define MX_SPI_REF2
	#define FAT_2_MX_SPI_UREF			2
	#define MX_SPI_CHANNEL_2		1
	#define MX_SPI_MOSI_PIN_2		-1
	#define MX_SPI_MOSI_PORT_2		port0
	#define MX_SPI_MOSI_TRIS_2		tris0
	#define MX_SPI_MISO_PIN_2		-1
	#define MX_SPI_MISO_PORT_2		port0
	#define MX_SPI_MISO_TRIS_2		tris0
	#define MX_SPI_SCK_PIN_2		-1
	#define MX_SPI_SCK_PORT_2		port0
	#define MX_SPI_SCK_TRIS_2		tris0
	#define MX_SPI_CS_PIN_2			0
	#define MX_SPI_CS_PORT_2		0
	#define MX_SPI_BMODE_2			1
	#define MX_SPI_PR_SCALE_2		4
	#define MX_SPI_PO_SCALE_2		1
	#define MX_SPI_INT_2			0
 #else
  #ifndef	MX_SPI_REF3
	#define MX_SPI_REF3
	#define FAT_2_MX_SPI_UREF			3
	#define MX_SPI_CHANNEL_3		1
	#define MX_SPI_MOSI_PIN_3		-1
	#define MX_SPI_MOSI_PORT_3		port0
	#define MX_SPI_MOSI_TRIS_3		tris0
	#define MX_SPI_MISO_PIN_3		-1
	#define MX_SPI_MISO_PORT_3		port0
	#define MX_SPI_MISO_TRIS_3		tris0
	#define MX_SPI_SCK_PIN_3		-1
	#define MX_SPI_SCK_PORT_3		port0
	#define MX_SPI_SCK_TRIS_3		tris0
	#define MX_SPI_CS_PIN_3			0
	#define MX_SPI_CS_PORT_3		0
	#define MX_SPI_BMODE_3			1
	#define MX_SPI_PR_SCALE_3		4
	#define MX_SPI_PO_SCALE_3		1
	#define MX_SPI_INT_3			0
  #else
   #ifndef	MX_SPI_REF4
	#define MX_SPI_REF4
	#define FAT_2_MX_SPI_UREF			4
	#define MX_SPI_CHANNEL_4		1
	#define MX_SPI_MOSI_PIN_4		-1
	#define MX_SPI_MOSI_PORT_4		port0
	#define MX_SPI_MOSI_TRIS_4		tris0
	#define MX_SPI_MISO_PIN_4		-1
	#define MX_SPI_MISO_PORT_4		port0
	#define MX_SPI_MISO_TRIS_4		tris0
	#define MX_SPI_SCK_PIN_4		-1
	#define MX_SPI_SCK_PORT_4		port0
	#define MX_SPI_SCK_TRIS_4		tris0
	#define MX_SPI_CS_PIN_4			0
	#define MX_SPI_CS_PORT_4		0
	#define MX_SPI_BMODE_4			1
	#define MX_SPI_PR_SCALE_4		4
	#define MX_SPI_PO_SCALE_4		1
	#define MX_SPI_INT_4			0
   #endif
  #endif
 #endif
#endif

#define FAT_2_SPI_Master_Init		CAL_APPEND(FC_CAL_SPI_Master_Init_, FAT_2_MX_SPI_UREF)
#define FAT_2_SPI_Master_Uninit	CAL_APPEND(FC_CAL_SPI_Master_Uninit_, FAT_2_MX_SPI_UREF)
#define FAT_2_SPI_Master_Byte		CAL_APPEND(FC_CAL_SPI_Master_Byte_, FAT_2_MX_SPI_UREF)

extern void FAT_2_SPI_Master_Init ();
extern void FAT_2_SPI_Master_Uninit ();
extern MX_UINT8 FAT_2_SPI_Master_Byte (MX_UINT8 DataOut);

//Flowcode Defines
#define FAT_2_FILE_CREATEDATE		0
#define FAT_2_FILE_CREATETIME		-1007448
#define FAT_2_FAT_TYPE				0		//0-FAT16(FAT) / 1-FAT32 / 2-FAT16&32

#include <string.h>

#ifndef	MX_FAT_ERR_FLAGS
	#define MX_FAT_ERR_FLAGS

	//Common Defines
	#define MX_ERR_NOCARD			0xFF
	#define MX_ERR_NORESP			0xFE
	#define MX_ERR_NOACK			0xFD
	#define MX_ERR_TOUT				0xFC
	#define MX_ERR_RESERVED			0xFB
	#define MX_ERR_BAD				0xFA
	#define MX_ERR_FREE				0xF0
	#define MX_ERR_FILENOTFOUND		0xEF
	#define MX_ERR_ROOTFULL			0xEE
	#define MX_ERR_SECTBYTES		0xED
	#define MX_ACK_FILEEMPTY		0x03
	#define MX_ACK_FILETYPE			0x02
	#define MX_ACK_EOF				0x01
	#define MX_ACK_OK				0x00
#endif

//Global Variables
MX_UINT8 FAT_2_mx_card_bufferl[256];		//512-Byte Global Buffer Variables
MX_UINT8 FAT_2_mx_card_bufferh[256];
MX_UINT8 FAT_2_mx_name_ext[12];			//11 byte fat file name: 8 MX_UINT8 filename + 3 MX_UINT8 extension
MX_UINT8 FAT_2_mx_file_entry;				//Directory entry of file
MX_UINT8 FAT_2_mx_sects_per_clust;			//Number of sectors per cluster    - Added BR 06/10
MX_UINT16 FAT_2_mx_root_sectors = 0;		//Number of sectors in the root directory
MX_UINT16 FAT_2_mx_fat_size = 0;			//FAT size in sectors
MX_UINT32 FAT_2_mx_fat_start = 0;			//Start address of FAT tables
MX_UINT32 FAT_2_mx_root_start = 0;			//Start address of root directory
MX_UINT32 FAT_2_mx_data_start = 0;			//Start address of the data
MX_UINT32 FAT_2_mx_file_size = 0;			//Size of file in bytes
MX_UINT32 FAT_2_mx_file_address = 0; 		//Start address of File
MX_UINT32 FAT_2_mx_file_sector = 1;		//Current sector of file
MX_UINT32 FAT_2_mx_folder_size = 0;		//Folder size in sectors
MX_UINT32 FAT_2_mx_folder_start = 0;		//Start address of Folder
MX_UINT32 FAT_2_mx_current_address = 0;	//Current address loaded in memory

#if (FAT_2_FAT_TYPE == 0)
	MX_UINT16 FAT_2_mx_cluster = 2;		//Current data FAT_2_mx_cluster in the memory
	#define FAT_2_SECT_ADDR_LEN			2
	#define FAT_2_FATS_PER_SECT			(512 / 2)	//2 bytes per fat record
	#define FAT_2_NOT_ADDRESS_MARKER		0xFFF0
	#define FAT_2_MX_EOF_MARKER			0xFFF7
#endif
#if (FAT_2_FAT_TYPE == 1)
	MX_UINT32 FAT_2_mx_cluster = 2;		//Current data FAT_2_mx_cluster in the memory
	#define FAT_2_mx_fat_system  			1
	#define FAT_2_SECT_ADDR_LEN			4
	#define FAT_2_FATS_PER_SECT			(512 / 4)	//4 bytes per fat record
	#define FAT_2_NOT_ADDRESS_MARKER		0x0FFFFFF0
	#define FAT_2_MX_EOF_MARKER			0x0FFFFFF7
#endif
#if (FAT_2_FAT_TYPE == 2)
	MX_UINT32 FAT_2_mx_cluster = 2;		//Current data FAT_2_mx_cluster in the memory
	MX_UINT8 FAT_2_mx_fat_system;			//Type of FAT file system in use on disk     - Added BR 07/10
	MX_UINT8 FAT_2_SECT_ADDR_LEN;			//Defines become variables
	MX_UINT16 FAT_2_FATS_PER_SECT;
	MX_UINT32 FAT_2_NOT_ADDRESS_MARKER;
	MX_UINT32 FAT_2_MX_EOF_MARKER;
#endif




//FAT16(0): //Macro function declarations

static MX_UINT8 FCD_FAT160_Init_FAT();
static MX_UINT8 FCD_FAT160_Open_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name);
static MX_UINT8 FCD_FAT160_Read_File_Sector();
static MX_SINT16 FCD_FAT160_Read_File_Length();
static MX_UINT8 FCD_FAT160_Move_To_Next_File_Sector(MX_UINT8 Force_Next_Sector);
static MX_UINT8 FCD_FAT160_Append_String_To_File(MX_STRING String, MX_UINT8 MSZ_String);
static MX_UINT8 FCD_FAT160_Write_File_Sector();
static MX_UINT8 FCD_FAT160_Create_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name);
static MX_UINT8 FCD_FAT160_Delete_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name);
static void FCD_FAT160_Write_Byte_To_Buffer(MX_SINT16 Address, MX_UINT8 Data);
static MX_UINT8 FCD_FAT160_Read_Byte_From_Buffer(MX_SINT16 Address);
static MX_UINT8 FCD_FAT160_Open_Folder(MX_STRING Folder_Name, MX_UINT8 MSZ_Folder_Name);
static MX_SINT16 FCD_FAT160_Scan_Current_Folder(MX_SINT16 Current_Idx, MX_UINT8 Scan_Type);
static MX_UINT8 FCD_FAT160_Read_Byte_From_Scan(MX_UINT8 idx);
static MX_UINT8 FCD_FAT160_MX_Init_Card();
static MX_UINT8 FCD_FAT160_MX_Send_Buffer(long address);
static MX_UINT8 FCD_FAT160_MX_Get_Buffer(long address);
static void FCD_FAT160_MX_Format_File_String(MX_STRING File_Name, MX_UINT8 MSZ_File_Name);
static void FCD_FAT160_MX_Add_Sector_To_File();
static void FCD_FAT160_MX_Clear_Buffer();
static MX_UINT8 FCD_FAT160_Read_Next_File_Sector();
static MX_UINT8 FCD_FAT160_MX_Send_Cmd(MX_UINT8 Cmd, MX_UINT32 Addr);



//FAT16(0): //Macro implementations


static MX_UINT8 FCD_FAT160_Init_FAT()
{
	
		MX_UINT8 retval;
		MX_UINT8 i, num_fats, sects_per_clust;
		MX_UINT8 iterations = 0;
		MX_UINT16 bytes_per_sect = 0;
		MX_UINT16 reserved_sectors;
		MX_UINT32 partition_start = 0;  //Start address of the partition
		MX_UINT32 root_size; //Number of 32 byte root entries.
		MX_Union32 Temp32;
		MX_Union16 Temp16;

		retval = FCD_FAT160_MX_Init_Card(); //Startup Card
		if (retval)
		return(retval); //Startup error or no card
		retval = FCD_FAT160_MX_Get_Buffer(0); //Read Master Boot Record if available

		Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x0B); //Bytes per sector - normally 512
		Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x0C);
		bytes_per_sect = Temp16.AsInt;

		while (bytes_per_sect != 512 && iterations < 20) //Search for valid partition table
		{
			Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x01C9); //Read start address of partition
			Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x01C8);
			Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x01C7);
			Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x01C6);
			partition_start = Temp32.AsLong;

			retval = FCD_FAT160_MX_Get_Buffer(partition_start); //Read Start of Partition (should also work for disks with no MBR or extended partitions)

			Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x0B); //Bytes per sector - normally 512
			Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x0C);
			bytes_per_sect = Temp16.AsInt;

			iterations = iterations + 1;
		}
		if (iterations == 20)															//BR Added 06/10 - Confirm that sector is correct size
			return MX_ERR_SECTBYTES;

		FAT_2_mx_sects_per_clust = FCD_FAT160_Read_Byte_From_Buffer(0x0D);								//Read number of sectors per FAT_2_mx_cluster

		Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x0E);										//Number of reserved sectors
		Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x0F);
		reserved_sectors = Temp16.AsInt;

		num_fats = FCD_FAT160_Read_Byte_From_Buffer(0x10);											//Num of copies of FAT - normally 2

		#if (FAT_2_FAT_TYPE == 2)
			if ( FCD_FAT160_Read_Byte_From_Buffer(0x55) == '3')									//Is this a FAT32 card?
			{
				FAT_2_mx_fat_system = 1;
				FAT_2_SECT_ADDR_LEN = 4;
				FAT_2_FATS_PER_SECT = 128;
				FAT_2_NOT_ADDRESS_MARKER = 0x0FFFFFF0;
				FAT_2_MX_EOF_MARKER = 0x0FFFFFF7;
			}
			else
			{
				FAT_2_mx_fat_system = 0;
				FAT_2_SECT_ADDR_LEN = 2;
				FAT_2_FATS_PER_SECT = 256;
				FAT_2_NOT_ADDRESS_MARKER = 0xFFF0;
				FAT_2_MX_EOF_MARKER = 0xFFF7;
			}
		#endif

		FAT_2_mx_fat_start = partition_start + reserved_sectors;									//start of FAT address space in sectors

		#if (FAT_2_FAT_TYPE == 0)																//FAT32 uses normal folder cluster for root

			Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x11);										//Size of root directory x 32 byte file/directory entries
			Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x12);
			root_size = Temp16.AsInt;

			if(root_size == 0)																//if root size not defined here
			{
				Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x24);									//Size of root directory x 32 byte file/directory entries
				Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x25);
				Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x26);
				Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x27);
				root_size = Temp32.AsLong;
			}
			FAT_2_mx_root_sectors = root_size >> 4;												//Number of sectors in the root directory

			Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x16);										//FAT size in sectors
			Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x17);
			FAT_2_mx_fat_size = Temp16.AsInt;

			FAT_2_mx_root_start = FAT_2_mx_fat_start + (num_fats * FAT_2_mx_fat_size);						//start of the root directory in sectors
			FAT_2_mx_data_start = FAT_2_mx_root_start + FAT_2_mx_root_sectors;								//start of the data FAT_2_mx_clusters in sectors

		#endif
		#if (FAT_2_FAT_TYPE == 1)																//FAT32 uses normal folder cluster for root

			FAT_2_mx_root_sectors = FAT_2_mx_sects_per_clust;

			Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x24);											//FAT size in sectors
			Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x25);
			Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x26);
			Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x27);
			FAT_2_mx_fat_size = Temp32.AsLong;

			Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x2C);										//first cluster address of root directory
			Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x2D);
			Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x2E);
			Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x2F);
			root_size = Temp32.AsLong;

			FAT_2_mx_data_start = FAT_2_mx_fat_start + (num_fats * FAT_2_mx_fat_size);						//start of the root directory in sectors
			FAT_2_mx_root_start = FAT_2_mx_data_start + ((root_size - 2) * FAT_2_mx_sects_per_clust);			//Move to sector containing start of file

		#endif
		#if (FAT_2_FAT_TYPE == 2)
			if (FAT_2_mx_fat_system == 0)																//FAT32 uses normal folder cluster for root
			{
				Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x11);										//Size of root directory x 32 byte file/directory entries
				Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x12);
				root_size = Temp16.AsInt;

				if(root_size == 0)																//if root size not defined here
				{
					Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x24);									//Size of root directory x 32 byte file/directory entries
					Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x25);
					Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x26);
					Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x27);
					root_size = Temp32.AsLong;
				}
				FAT_2_mx_root_sectors = root_size >> 4;												//Number of sectors in the root directory

				Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x16);										//FAT size in sectors
				Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x17);
				FAT_2_mx_fat_size = Temp16.AsInt;

				FAT_2_mx_root_start = FAT_2_mx_fat_start + (num_fats * FAT_2_mx_fat_size);						//start of the root directory in sectors
				FAT_2_mx_data_start = FAT_2_mx_root_start + FAT_2_mx_root_sectors;								//start of the data FAT_2_mx_clusters in sectors

			}
			if (FAT_2_mx_fat_system == 1)																//FAT32 uses normal folder cluster for root
			{
				FAT_2_mx_root_sectors = FAT_2_mx_sects_per_clust;

				Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x24);										//FAT size in sectors
				Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x25);
				Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x26);
				Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x27);
				FAT_2_mx_fat_size = Temp32.AsLong;

				Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(0x2C);										//first cluster address of root directory
				Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(0x2D);
				Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(0x2E);
				Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(0x2F);
				root_size = Temp32.AsLong;

				FAT_2_mx_data_start = FAT_2_mx_fat_start + (num_fats * FAT_2_mx_fat_size);						//start of the root directory in sectors
				FAT_2_mx_root_start = FAT_2_mx_data_start + ((root_size - 2) * FAT_2_mx_sects_per_clust);			//Move to sector containing start of file
			}
		#endif

		FAT_2_mx_folder_size = FAT_2_mx_root_sectors;
		FAT_2_mx_folder_start = FAT_2_mx_root_start;

		return retval;

}

static MX_UINT8 FCD_FAT160_Open_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name)
{
	
		MX_UINT8 i;
		MX_UINT8 name_comp[11];
		MX_UINT8 address[4];
		MX_UINT16 idx_fat;
		MX_UINT16 scount;

		MX_UINT16 Idx;

		#if (FAT_2_FAT_TYPE == 0)
			MX_UINT16 fat_pointer = 0xFFFF;
		#endif
		#if (FAT_2_FAT_TYPE == 1)
			MX_UINT32 fat_pointer = 0x0FFFFFFF;
		#endif
		#if (FAT_2_FAT_TYPE == 2)
			MX_UINT32 fat_pointer;
			if (FAT_2_mx_fat_system == 0)
				fat_pointer = 0xFFFF;
			else fat_pointer = 0x0FFFFFFF;
		#endif
		MX_UINT32 fat_address;

		MX_Union32 Temp32;

		FCD_FAT160_MX_Format_File_String(File_Name, MSZ_File_Name);							//Convert filename to 8.3 format
		scount = 0;
		FAT_2_mx_current_address = FAT_2_mx_folder_start;										//Move to start of root

		while (scount < FAT_2_mx_folder_size)
		{
			FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);										//Read sector of root directory
			for(i=0;i<16;i++)														//16 file or directory references per sector
			{
				Idx = i << 5;

				name_comp[0] = FCD_FAT160_Read_Byte_From_Buffer(0 + Idx);					//Move DOS 8.3 Filename into 2nd comparison buffer
				name_comp[1] = FCD_FAT160_Read_Byte_From_Buffer(1 + Idx);
				name_comp[2] = FCD_FAT160_Read_Byte_From_Buffer(2 + Idx);
				name_comp[3] = FCD_FAT160_Read_Byte_From_Buffer(3 + Idx);
				name_comp[4] = FCD_FAT160_Read_Byte_From_Buffer(4 + Idx);
				name_comp[5] = FCD_FAT160_Read_Byte_From_Buffer(5 + Idx);
				name_comp[6] = FCD_FAT160_Read_Byte_From_Buffer(6 + Idx);
				name_comp[7] = FCD_FAT160_Read_Byte_From_Buffer(7 + Idx);
				name_comp[8] = FCD_FAT160_Read_Byte_From_Buffer(8 + Idx);
				name_comp[9] = FCD_FAT160_Read_Byte_From_Buffer(9 + Idx);
				name_comp[10] = FCD_FAT160_Read_Byte_From_Buffer(10 + Idx);

				if (FCI_COMPARE(FAT_2_mx_name_ext,11,name_comp,11,1) == 0)				//Perform filename comparison
				{
					FAT_2_mx_file_entry = i;												//Store file address
					FAT_2_mx_file_address = FAT_2_mx_current_address;
					FAT_2_mx_file_sector = 1;

					Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(26 + Idx);				//Read Cluster of data start
					Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(27 + Idx);
					Temp32.AsByte[2] = 0;
					Temp32.AsByte[3] = 0;

					#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
						if(FAT_2_mx_fat_system == 1)
						{
							Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(20 + Idx);
							Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(21 + Idx);
						}
					#endif

					FAT_2_mx_cluster = Temp32.AsLong;

					Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(28 + Idx);				//Read Filesize in bytes
					Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(29 + Idx);
					Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(30 + Idx);
					Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(31 + Idx);
					FAT_2_mx_file_size = Temp32.AsLong;

					if (FAT_2_mx_cluster == 0)											//Empty File - Assign a free FAT_2_mx_cluster
					{
						idx_fat = 1;
						fat_address = FAT_2_mx_fat_start;								//Move to start of FAT
						FCD_FAT160_MX_Get_Buffer(fat_address);								//Read FAT sector
						while (fat_pointer != 0)								//Scan FAT for free entry
						{
							idx_fat = idx_fat + 1;
							if(idx_fat == FAT_2_FATS_PER_SECT)				//If at the end of the FAT sector
							{
								fat_address = fat_address + 1;
								FCD_FAT160_MX_Get_Buffer(fat_address);						//Read next FAT sector
								idx_fat = 0;
							}

							Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(idx_fat * FAT_2_SECT_ADDR_LEN);			//Extract data FAT_2_mx_cluster address
							Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 1);
							Temp32.AsByte[2] = 0;
							Temp32.AsByte[3] = 0;

							#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
								if(FAT_2_mx_fat_system == 1)
								{
									Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 2);
									Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 3);

								}
							#endif

							fat_pointer = Temp32.AsLong;
						}

						FCD_FAT160_Write_Byte_To_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN), 0xFF);						//Write end of file marker into new FAT address
						FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 1), 0xFF);
						#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
							if(FAT_2_mx_fat_system == 1)
							{
								FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 2), 0xFF);
								FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 3), 0x0F);
							}
						#endif
						FCD_FAT160_MX_Send_Buffer(fat_address);
						FCD_FAT160_MX_Send_Buffer(fat_address + FAT_2_mx_fat_size);										//Mirror data onto FAT 2

						FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);												//Read sector of root directory containing file
						fat_address = ((fat_address - FAT_2_mx_fat_start) * FAT_2_FATS_PER_SECT) + idx_fat;
						FAT_2_mx_cluster = fat_address;

						Temp32.AsLong = FAT_2_mx_cluster;

						FCD_FAT160_Write_Byte_To_Buffer(26 + Idx, Temp32.AsByte[0]);									//Write new FAT_2_mx_cluster value
						FCD_FAT160_Write_Byte_To_Buffer(27 + Idx, Temp32.AsByte[1]);
						#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
							if(FAT_2_mx_fat_system == 1)
							{
								FCD_FAT160_Write_Byte_To_Buffer(20 + Idx, Temp32.AsByte[2]);
								FCD_FAT160_Write_Byte_To_Buffer(21 + Idx, Temp32.AsByte[3]);
							}
						#endif
						FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);												//Write FAT_2_mx_cluster location to card
					}

					FAT_2_mx_current_address = FAT_2_mx_data_start + ((FAT_2_mx_cluster - 2) * FAT_2_mx_sects_per_clust);		//Move to sector containing start of file   - BR 06/10 was *32
					FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);													//Read sector
					return MX_ACK_OK;
				}
			}
			FAT_2_mx_current_address = FAT_2_mx_current_address + 1;
			scount = scount + 1;																		//Move to next sector of folder
		}
		return MX_ERR_FILENOTFOUND;																		//File not found

}

static MX_UINT8 FCD_FAT160_Read_File_Sector()
{
	
		return FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);		//Read sector

}

static MX_SINT16 FCD_FAT160_Read_File_Length()
{
	
		long temp;
		temp = FAT_2_mx_file_sector << 9;
		if (temp <= FAT_2_mx_file_size)					//If file size greater then sector limit
			return 512;								//Return Sector Full

		temp = FAT_2_mx_file_size % 512;
		return (temp);								//Return index of next available byte

}

static MX_UINT8 FCD_FAT160_Move_To_Next_File_Sector(MX_UINT8 Force_Next_Sector)
{
	
		MX_UINT8 retval;
		retval = FCD_FAT160_Read_Next_File_Sector();				//Try to move to the next sector
		if (Force_Next_Sector)							//If forcing next sector
		{
			if(retval != 0x01)
				return retval;							//Next sector exists and has been read (0) or error with sector chain

			FCD_FAT160_MX_Add_Sector_To_File();					//If last sector in FAT chain then create new link
			//FAT_2_mx_file_sector = FAT_2_mx_file_sector + 1;		//Increment file sector
			return MX_ACK_OK;
		}
		return retval;

}

static MX_UINT8 FCD_FAT160_Append_String_To_File(MX_STRING String, MX_UINT8 MSZ_String)
{
	
		MX_UINT8 idx;
		MX_SINT16 length;
		MX_UINT8 retval;
		MX_UINT8 offset = 0;
		MX_UINT16 Idx16;

		MX_Union32 Temp32;

		for (idx=0;idx<MSZ_String;idx++)
		{
			if(String[idx] == 0)
				MSZ_String = idx;
		}

		length = FCD_FAT160_Read_File_Length();				//Get next empty MX_UINT8acter position
		while (length == 512)						//While MX_UINT8acters in sector full
		{
			retval = FCD_FAT160_Read_Next_File_Sector();		//Load next sector
			if (retval == 0x01)						//If end of file then next sector will be empty
				length = -1;
			else
				length = FCD_FAT160_Read_File_Length();		//Else end of data located in this sector
		}

		if (length == -1)
			length = 512;

		for (idx = 0; idx < MSZ_String; idx++)		//Loop through each MX_UINT8acter in string
		{
			if((length + idx) == 512)				//if string extends onto another sector
			{
				length = 0;
				offset = idx;

				FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);			//Write string data in current sector to card
				retval = FCD_FAT160_Read_Next_File_Sector();		//Load next sector

				if (retval == 0x01)
				{
					FCD_FAT160_MX_Add_Sector_To_File();			//If last sector in FAT chain then create new link
				}

				if (retval > 0x01)
					return retval;										//Error occurred - return error
			}

			FCD_FAT160_Write_Byte_To_Buffer((length + (idx - offset)), String[idx]);		//Write MX_UINT8acter from string into buffer
		}

		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);										//Write string data in current sector to card
		FAT_2_mx_file_size = FAT_2_mx_file_size + MSZ_String;								//Update file length
		FCD_FAT160_MX_Get_Buffer(FAT_2_mx_file_address);											//Read file address

		Temp32.AsLong = FAT_2_mx_file_size;

		Idx16 = 28 + (FAT_2_mx_file_entry << 5);

		FCD_FAT160_Write_Byte_To_Buffer(Idx16++, Temp32.AsByte[0]);				//Update file length in buffer
		FCD_FAT160_Write_Byte_To_Buffer(Idx16++, Temp32.AsByte[1]);
		FCD_FAT160_Write_Byte_To_Buffer(Idx16++, Temp32.AsByte[2]);
		FCD_FAT160_Write_Byte_To_Buffer(Idx16, Temp32.AsByte[3]);

		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_file_address);									//Update file length on card
		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_file_address + FAT_2_mx_fat_size);						//Mirror data onto FAT 2
		FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);									//Read current sector
		return MX_ACK_OK;														//String appended to file

}

static MX_UINT8 FCD_FAT160_Write_File_Sector()
{
	
		short Idx;

		MX_Union32 Temp32;

		if ((FAT_2_mx_file_size >> 9) == (FAT_2_mx_file_sector - 1))	//Is this the last sector of the file
			FAT_2_mx_file_size = (FAT_2_mx_file_size + (512 - FCD_FAT160_Read_File_Length()));

		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);								//Write string data in current sector to card
		FCD_FAT160_MX_Get_Buffer(FAT_2_mx_file_address);									//Read file address

		Temp32.AsLong = FAT_2_mx_file_size;

		Idx = 28 + (FAT_2_mx_file_entry << 5);
		FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp32.AsByte[0]);					//Update file length in buffer
		FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp32.AsByte[1]);
		FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp32.AsByte[2]);
		FCD_FAT160_Write_Byte_To_Buffer(Idx, Temp32.AsByte[3]);

		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_file_address);								//Update file length on card
		FCD_FAT160_MX_Send_Buffer(FAT_2_mx_file_address + FAT_2_mx_fat_size);					//Mirror data onto FAT 2
		FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);								//Read current sector

		return MX_ACK_OK;

}

static MX_UINT8 FCD_FAT160_Create_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name)
{
	
		MX_UINT8 i, j;
		MX_UINT16 Idx;

		MX_Union16 Temp16;

		if ( FCD_FAT160_Open_File(File_Name, MSZ_File_Name) != MX_ERR_FILENOTFOUND )
			return 0x01;													//File Already exists

		FCD_FAT160_MX_Format_File_String(File_Name, MSZ_File_Name);					//Convert filename to 8.3 format
		FAT_2_mx_current_address = FAT_2_mx_folder_start;								//Move to start of root
		while (FAT_2_mx_current_address < (FAT_2_mx_folder_start + FAT_2_mx_folder_size))
		{
			FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);								//Read sector of root directory
			for(i=0;i<16;i++)												//16 file or directory references per sector
			{
				Idx = i << 5;
				j = FCD_FAT160_Read_Byte_From_Buffer(Idx);
				if (( j == 0xe5) || ( j == 0x00))							//Deleted or unused entry
				{
					for (j=0;j<11;j++)
					{
						FCD_FAT160_Write_Byte_To_Buffer(Idx++, FAT_2_mx_name_ext[j]);
					}

					FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0x20);						//File Attribute
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0x18);						//Reserved for NT
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0);							//Creation time
					Temp16.AsInt = FAT_2_FILE_CREATETIME;
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[0]);
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[1]);
					Temp16.AsInt = FAT_2_FILE_CREATEDATE;
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[0]);		//Creation date
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[1]);
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[0]);		//Access date
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[1]);
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0x00);
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0x00);
					Temp16.AsInt = FAT_2_FILE_CREATETIME;
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[0]);		//Modified time 0 no modification entry
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[1]);
					Temp16.AsInt = FAT_2_FILE_CREATEDATE;
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[0]);		//Modified date
					FCD_FAT160_Write_Byte_To_Buffer(Idx++, Temp16.AsByte[1]);

					for (j=26;j<32;j++)												//Sector location and length
					{
						FCD_FAT160_Write_Byte_To_Buffer(Idx++, 0);
					}
					FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);
					return MX_ACK_OK;												//File created
				}
			}
			FAT_2_mx_current_address = FAT_2_mx_current_address + 1;
		}
		return MX_ERR_ROOTFULL;														//No space left in root directory

}

static MX_UINT8 FCD_FAT160_Delete_File(MX_STRING File_Name, MX_UINT8 MSZ_File_Name)
{
	
		MX_UINT16 scount;
		MX_UINT8 name_comp[11];
		MX_UINT32 fat_address;
		MX_UINT8 i;
		MX_UINT16 Idx;

		MX_Union16 Temp16;

		#if (FAT_2_FAT_TYPE == 0)
			MX_UINT16 temp_FAT_2_mx_cluster;
		#endif
		#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
			MX_UINT32 temp_FAT_2_mx_cluster;
		#endif

		FCD_FAT160_MX_Format_File_String(File_Name, MSZ_File_Name);						//Convert filename to 8.3 format
		scount = 0;
		FAT_2_mx_current_address = FAT_2_mx_folder_start;									//Move to start of root
		while (scount <= FAT_2_mx_folder_size)
		{
			FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);									//Read sector of root directory
			for(i=0;i<16;i++)													//16 file or directory references per sector
			{
				Idx = i << 5;

				name_comp[0] = FCD_FAT160_Read_Byte_From_Buffer(Idx);						//Move DOS 8.3 Filename into 2nd comparison buffer
				name_comp[1] = FCD_FAT160_Read_Byte_From_Buffer(1 + Idx);
				name_comp[2] = FCD_FAT160_Read_Byte_From_Buffer(2 + Idx);
				name_comp[3] = FCD_FAT160_Read_Byte_From_Buffer(3 + Idx);
				name_comp[4] = FCD_FAT160_Read_Byte_From_Buffer(4 + Idx);
				name_comp[5] = FCD_FAT160_Read_Byte_From_Buffer(5 + Idx);
				name_comp[6] = FCD_FAT160_Read_Byte_From_Buffer(6 + Idx);
				name_comp[7] = FCD_FAT160_Read_Byte_From_Buffer(7 + Idx);
				name_comp[8] = FCD_FAT160_Read_Byte_From_Buffer(8 + Idx);
				name_comp[9] = FCD_FAT160_Read_Byte_From_Buffer(9 + Idx);
				name_comp[10] = FCD_FAT160_Read_Byte_From_Buffer(10 + Idx);

				if (FCI_COMPARE(FAT_2_mx_name_ext,11,name_comp,11,1) == 0)				//Perform filename comparison
				{
					Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(26 + Idx);				//Read Cluster of data start
					Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(27 + Idx);
					FAT_2_mx_cluster = Temp16.AsInt;

					FCD_FAT160_Write_Byte_To_Buffer(26 + Idx, 0);								//Overwrite FAT_2_mx_cluster value
					FCD_FAT160_Write_Byte_To_Buffer(27 + Idx, 0);
					#if(FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
						if (FAT_2_mx_fat_system == 1)
						{
							FCD_FAT160_Write_Byte_To_Buffer(20 + Idx, 0);
							FCD_FAT160_Write_Byte_To_Buffer(21 + Idx, 0);
						}
					#endif

					FCD_FAT160_Write_Byte_To_Buffer(28 + Idx, 0);								//Clear file size
					FCD_FAT160_Write_Byte_To_Buffer(29 + Idx, 0);
					FCD_FAT160_Write_Byte_To_Buffer(30 + Idx, 0);
					FCD_FAT160_Write_Byte_To_Buffer(31 + Idx, 0);
					FCD_FAT160_Write_Byte_To_Buffer(Idx, 0xe5);								//Set first byte to free file flag
					FCD_FAT160_MX_Send_Buffer(FAT_2_mx_current_address);								//Write the free file flag to the card

					while (FAT_2_mx_cluster >= 0x02 && FAT_2_mx_cluster <= (FAT_2_MX_EOF_MARKER + 1))			//While end of file not reached
					{
						if (FAT_2_mx_cluster > FAT_2_MX_EOF_MARKER)
							return 0xFE;										//Problem with FAT entry

						fat_address = FAT_2_mx_fat_start;								//Move to start of FAT
						while(FAT_2_mx_cluster >= FAT_2_FATS_PER_SECT)
						{
							fat_address = fat_address + 1;						//Move to next sector of FAT
							FAT_2_mx_cluster = FAT_2_mx_cluster - FAT_2_FATS_PER_SECT;
						}
						FCD_FAT160_MX_Get_Buffer(fat_address);								//Read FAT sector

						temp_FAT_2_mx_cluster = FAT_2_mx_cluster;
						Temp16.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(temp_FAT_2_mx_cluster * FAT_2_FATS_PER_SECT);			//Read next FAT_2_mx_cluster value
						Temp16.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer((temp_FAT_2_mx_cluster * FAT_2_FATS_PER_SECT) + 1);
						FAT_2_mx_cluster = Temp16.AsInt;

						FCD_FAT160_Write_Byte_To_Buffer((temp_FAT_2_mx_cluster * FAT_2_FATS_PER_SECT), 0x00);				//Overwrite FAT entry
						FCD_FAT160_Write_Byte_To_Buffer(((temp_FAT_2_mx_cluster * FAT_2_FATS_PER_SECT) + 1), 0x00);

						FCD_FAT160_MX_Send_Buffer(fat_address);
						FCD_FAT160_MX_Send_Buffer(fat_address + FAT_2_mx_fat_size);				//Mirror data onto FAT 2
					}
					return 0;													//File deleted correctly
				}
			}
			scount = scount + 1;
			FAT_2_mx_current_address = FAT_2_mx_current_address + 1;
		}
		return MX_ERR_FILENOTFOUND;												//File not found

}

static void FCD_FAT160_Write_Byte_To_Buffer(MX_SINT16 Address, MX_UINT8 Data)
{
	
		if (Address > 255)				//BufferH
		{
			Address = Address - 256;
			FAT_2_mx_card_bufferh[Address] = Data;
		}
		else							//BufferL
		{
			FAT_2_mx_card_bufferl[Address] = Data;
		}

}

static MX_UINT8 FCD_FAT160_Read_Byte_From_Buffer(MX_SINT16 Address)
{
	
		if (Address > 255)						//BufferH
		{
			Address = Address - 256;
			return (FAT_2_mx_card_bufferh[Address]);
		}
		else return (FAT_2_mx_card_bufferl[Address]);	//BufferL

}

static MX_UINT8 FCD_FAT160_Open_Folder(MX_STRING Folder_Name, MX_UINT8 MSZ_Folder_Name)
{
	
	// ".." - Up a level
	// "root" - Root directory
	// "foldername" - Down a level

		MX_UINT8 i;
		MX_UINT16 scount;
		MX_UINT8 name_comp[11];
		MX_UINT16 Idx;

		MX_Union32 Temp32;

		//Root Directory
		if (Folder_Name[0] == 'r' && Folder_Name[1] == 'o' && Folder_Name[2] == 'o' && Folder_Name[3] == 't')
		{
			FAT_2_mx_folder_start = FAT_2_mx_root_start;		//Assign root start address to folder start
			FAT_2_mx_folder_size = FAT_2_mx_root_sectors;		//Assign root size to folder size
			return (0);								//Root Directory Specified
		}

		//Up a level
		if (Folder_Name[0] == '.' && Folder_Name[1] == '.')
		{
			FAT_2_mx_name_ext[0] = 0x2E;			// Assign search string with ".."
			FAT_2_mx_name_ext[1] = 0x2E;
			FAT_2_mx_name_ext[2] = 0x20;
			FAT_2_mx_name_ext[3] = 0x20;
			FAT_2_mx_name_ext[4] = 0x20;
			FAT_2_mx_name_ext[5] = 0x20;
			FAT_2_mx_name_ext[6] = 0x20;
			FAT_2_mx_name_ext[7] = 0x20;
			FAT_2_mx_name_ext[8] = 0x20;
			FAT_2_mx_name_ext[9] = 0x20;
			FAT_2_mx_name_ext[10] = 0x20;
		}

		else
			FCD_FAT160_MX_Format_File_String(Folder_Name, MSZ_Folder_Name);					//Format folder string to match 8 MX_UINT8acter folder name

		scount = 0;
		FAT_2_mx_current_address = FAT_2_mx_folder_start;										//Move to start of folder
		while (scount < FAT_2_mx_folder_size)
		{
			FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);										//Read sector of root directory
			for(i=0;i<16;i++)														//16 file or directory references per sector
			{
				Idx = i << 5;

				name_comp[0] = FCD_FAT160_Read_Byte_From_Buffer(Idx);					//Move DOS 8.3 Filename into 2nd comparison buffer
				name_comp[1] = FCD_FAT160_Read_Byte_From_Buffer(1 + Idx);
				name_comp[2] = FCD_FAT160_Read_Byte_From_Buffer(2 + Idx);
				name_comp[3] = FCD_FAT160_Read_Byte_From_Buffer(3 + Idx);
				name_comp[4] = FCD_FAT160_Read_Byte_From_Buffer(4 + Idx);
				name_comp[5] = FCD_FAT160_Read_Byte_From_Buffer(5 + Idx);
				name_comp[6] = FCD_FAT160_Read_Byte_From_Buffer(6 + Idx);
				name_comp[7] = FCD_FAT160_Read_Byte_From_Buffer(7 + Idx);
				name_comp[8] = FCD_FAT160_Read_Byte_From_Buffer(8 + Idx);
				name_comp[9] = FCD_FAT160_Read_Byte_From_Buffer(9 + Idx);
				name_comp[10] = FCD_FAT160_Read_Byte_From_Buffer(10 + Idx);

				if (FCI_COMPARE(FAT_2_mx_name_ext,11,name_comp,11,1) == 0)				//Perform filename comparison
				{
					Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(26 + Idx);							//Read Cluster of folder start
					Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer(27 + Idx);
					Temp32.AsByte[2] = 0;
					Temp32.AsByte[3] = 0;

					#if	(FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
						if (FAT_2_mx_fat_system == 1)
						{
							Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer(20 + Idx);
							Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer(21 + Idx);
						}
					#endif

					FAT_2_mx_cluster = Temp32.AsLong;

					if (FAT_2_mx_cluster > 1)
					{
						FAT_2_mx_folder_start = FAT_2_mx_data_start + ((FAT_2_mx_cluster - 2) * FAT_2_mx_sects_per_clust);		//Assign folder start address - BR 06/10 was * 32
						FAT_2_mx_folder_size = FAT_2_mx_sects_per_clust;											//Assign folder size - BR 06/10 was *32											//Assign folder size
					}
					else
					{
						FAT_2_mx_folder_start = FAT_2_mx_root_start;							//Assign root start address to folder start
						FAT_2_mx_folder_size = FAT_2_mx_root_sectors;							//Assign root size to folder size
					}
					return MX_ACK_OK;												//Folder found and moved
				}
			}
			FAT_2_mx_current_address = FAT_2_mx_current_address + 1;
			scount = scount + 1;													//Move to next sector of folder
		}
		return MX_ERR_FILENOTFOUND;													//Folder not found

}

static MX_SINT16 FCD_FAT160_Scan_Current_Folder(MX_SINT16 Current_Idx, MX_UINT8 Scan_Type)
{
	
		MX_UINT8 i;
		MX_UINT16 Idx;

		if (Current_Idx < (FAT_2_mx_folder_size * 16))
		{
			FAT_2_mx_current_address = FAT_2_mx_folder_start;							//Move to start of folder
			while(Current_Idx >= 16)										//While address is not in the current sector
			{
				Current_Idx = Current_Idx - 16;								//Modify address value
				FAT_2_mx_current_address = FAT_2_mx_current_address + 1;				//Increment sector address
			}

			FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);								//Read sector of root directory

			Idx = Current_Idx * 32;

			i = FCD_FAT160_Read_Byte_From_Buffer(Idx);
			if ((i == 0xe5) || (i == 0x00))  								//Deleted or unused entry
				return MX_ACK_FILEEMPTY;									//Address is empty

			if ( FCD_FAT160_Read_Byte_From_Buffer((Idx) + 2) == 0x00)
				return MX_ACK_FILEEMPTY;									//Address is empty

			if(Scan_Type)	//scan for folder
			{
				if (( FCD_FAT160_Read_Byte_From_Buffer(Idx + 11) & 0x10) == 0)			//If a file has been found
					return MX_ACK_FILETYPE;									//Address in use but incorrect data type
			}
			else			//scan for file
			{
				if (( FCD_FAT160_Read_Byte_From_Buffer(Idx + 11) & 0x20) == 0)			//If a folder has been found
					return MX_ACK_FILETYPE;									//Address in use but incorrect data type
			}

			for (i=0;i<11;i++)
				FAT_2_mx_name_ext[i] = FCD_FAT160_Read_Byte_From_Buffer(Idx + i);			//Read string from address

			if(Scan_Type == 0)												//If scanning for a file then rearrange 8.3 filename back into string
			{
				for (i=0;i<7;i++)
				{
					if (FAT_2_mx_name_ext[i] == 0x20)								//If a padding space has been found
						break;
				}
				FAT_2_mx_name_ext[i] = '.';										//Add the '.' seperator to the filename
				FAT_2_mx_name_ext[i + 1] = FCD_FAT160_Read_Byte_From_Buffer(Idx + 8);
				FAT_2_mx_name_ext[i + 2] = FCD_FAT160_Read_Byte_From_Buffer(Idx + 9);
				FAT_2_mx_name_ext[i + 3] = FCD_FAT160_Read_Byte_From_Buffer(Idx + 10);
				for (i=i+4;i<12;i++)
					FAT_2_mx_name_ext[i] = ' ';
			}
			return MX_ACK_OK;												//File/folder found and stored into string array
		}
		return MX_ACK_EOF;													//End of folder reached

}

static MX_UINT8 FCD_FAT160_Read_Byte_From_Scan(MX_UINT8 idx)
{
	
		if(idx > 11)
			return 0;				//String buffer 12 MX_UINT8s long max
		return (FAT_2_mx_name_ext[idx]);	//Return MX_UINT8acter from string

}

static MX_UINT8 FCD_FAT160_MX_Init_Card()
{
	
		MX_UINT8 RetVal;
		MX_SINT16 i;

		delay_ms(50);														//Wait for card to power up

		//Init SPI
		FAT_2_SPI_Master_Init();							//Call initialise function

		FC_CAL_Bit_High_DDR (FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_TRIS, FAT_2_MX_SPI_FAT_CS_PIN);	// Chip Select pin is disabled

		for(i = 0; i < 10; i++)												//Start CARD in SPI mode
		{
			FAT_2_SPI_Master_Byte(0xFF);					//Send 10*8=80 clock pulses
		}

		FC_CAL_Bit_Low ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);		// Chip Select pin is enabled
		delay_us(50);														//Wait 50us

		//Command 0 - Goto Idle State - Resets card
		RetVal = FCD_FAT160_MX_Send_Cmd(0,0);

		FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);		// Chip Select pin is disabled

		if (RetVal != 1)
			return MX_ERR_NOCARD;											//Card not initialising or not present

		delay_us(50);														//Wait 50us
		FC_CAL_Bit_Low ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);		// Chip Select pin is enabled

		//Command 1 - Send Operating Condition - Reports the status of the card
		i = 10000;
		do
		{
			RetVal = FCD_FAT160_MX_Send_Cmd(1,0);

			FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);	//CARD-Disabled
		}
		while ((RetVal) && (i--));				//Loop while processing command 1

		if (RetVal)
			return MX_ERR_NORESP;				//Card not responding


		//Need a good way of applying this speed update!!!

		//FAT_2_SPI_Master_Uninit();				//Disable Low Speed
		//FAT_2_FAT.AsByteus_mode = 1;					//SPI Bus Mode	//Check this value
		//FAT_2_SPI_Master_Init ();				//Enable Hi Speed

		return MX_ACK_OK;						//Card Ready

}

static MX_UINT8 FCD_FAT160_MX_Send_Buffer(long address)
{
	
		MX_UINT16 idx;
		MX_UINT8 retval;

		address = address << 9;

		retval = FCD_FAT160_MX_Send_Cmd(0x18, address);

		if (retval)
		{
			FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);			//CARD-Disabled
			FAT_2_SPI_Master_Byte(0xFF);
			return MX_ERR_NOACK;													//Command not acknowledged
		}

		FAT_2_SPI_Master_Byte(0xFE);													//Send Start Byte
		for (idx=0; idx < 256; idx++)												//Write Low Buffer
		{
			FAT_2_SPI_Master_Byte(FAT_2_mx_card_bufferl[idx]);
		}
		for (idx=0; idx < 256; idx++)												//Write High Buffer
		{
			FAT_2_SPI_Master_Byte(FAT_2_mx_card_bufferh[idx]);
		}
		FAT_2_SPI_Master_Byte(0xFF);								//Send 2 dummy bytes to skip CRC
		FAT_2_SPI_Master_Byte(0xFF);
		idx = 10000;
		retval = FAT_2_SPI_Master_Byte(0xFF);					//Check if CARD is still busy
		while((retval != 0xFF) && idx)
		{
			retval = FAT_2_SPI_Master_Byte(0xFF);				//Wait until CARD is not busy anymore
			idx = idx - 1;
		}

		FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);				// Chip Select pin is disabled

		if (idx == 0)
			return MX_ERR_TOUT;					//Read timed out

		return MX_ACK_OK;						//Write Complete

}

static MX_UINT8 FCD_FAT160_MX_Get_Buffer(long address)
{
	
		MX_SINT16 idx;
		MX_UINT16 CRC;
		MX_UINT8 temp;
		MX_UINT16 count;

		address = address << 9;

		FCD_FAT160_MX_Clear_Buffer();

		temp = FCD_FAT160_MX_Send_Cmd(0x11, address);

		if (temp)
		{
			FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);			//CARD-Disabled
			FAT_2_SPI_Master_Byte(0xFF);
			return MX_ERR_NOACK;													//Read Not Acknowledged
		}

		count = 10000;
		do
		{
			temp = FAT_2_SPI_Master_Byte(0xFF);
		}
		while ((temp != 0xFE) && (count--));			//Wait for data ready

		if (count == 0)
			return MX_ERR_TOUT	;													//Read Timed Out

		for (idx=0; idx < 256; idx++)												//Read Low Buffer
		{
			FAT_2_mx_card_bufferl[idx] = FAT_2_SPI_Master_Byte(0xFF);
		}

		for (idx=0; idx < 256; idx++)												//Read High Buffer
		{
			FAT_2_mx_card_bufferh[idx] = FAT_2_SPI_Master_Byte(0xFF);
		}

		CRC = FAT_2_SPI_Master_Byte(0xFF);						//Read 16-Bit CRC
		CRC = CRC << 8;
		CRC = CRC | FAT_2_SPI_Master_Byte(0xFF);

		FC_CAL_Bit_High ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);				// Chip Select pin is disabled
		FAT_2_SPI_Master_Byte(0xFF);								//Trailing byte
		return MX_ACK_OK;															//Read Complete

}

static void FCD_FAT160_MX_Format_File_String(MX_STRING File_Name, MX_UINT8 MSZ_File_Name)
{
	
		MX_UINT8 i;

		for (i=0;i<11;i++)
			FAT_2_mx_name_ext[i] = 0x20;											//Fill name variable with spaces

		FCI_TOUPPER(File_Name,MSZ_File_Name,File_Name,MSZ_File_Name);		//convert to uppercase

		for (i=0; i<8 && *File_Name != '.' && *File_Name; i++)				//Copy file name to comparison variable
			FAT_2_mx_name_ext[i] = *File_Name++;

		if(*File_Name == '.')												//Find the '.' seperator
		{
			File_Name++;													//and then shift the extension
			for(i=8;i<11 && *File_Name; i++)
				FAT_2_mx_name_ext[i] = *File_Name++;
		}

}

static void FCD_FAT160_MX_Add_Sector_To_File()
{
	
		MX_UINT32 idx_fat;
		MX_UINT32 fat_address;

		#if (FAT_2_FAT_TYPE == 0)
			MX_UINT16 fat_pointer = 0xFFFF;				//16-bit FAT pointer
		#endif
		#if (FAT_2_FAT_TYPE == 1)
			MX_UINT32 fat_pointer = 0x0FFFFFFF;			//32-bit FAT pointer
		#endif
		#if (FAT_2_FAT_TYPE == 2)
			MX_UINT32 fat_pointer;
			if (FAT_2_mx_fat_system == 1)
				fat_pointer = 0x0FFFFFFF;					//32-bit FAT pointer
			else
				fat_pointer = 0xFFFF;						//16-bit FAT pointer
		#endif

		MX_Union32 Temp32;

		idx_fat = 1;
		fat_address = FAT_2_mx_fat_start;							//Move to start of FAT
		FCD_FAT160_MX_Get_Buffer(fat_address);							//Read FAT sector
		while (fat_pointer > 0)								//Scan FAT for free entry
		{
			idx_fat = (long) idx_fat + 1;					//Increment FAT address - Start at address 2
			if(idx_fat == FAT_2_FATS_PER_SECT)					//If at the end of the FAT sector
			{
				fat_address = fat_address + 1;
				FCD_FAT160_MX_Get_Buffer(fat_address);					//Read next FAT sector
				idx_fat = 0;
			}

			Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(idx_fat * FAT_2_SECT_ADDR_LEN);			//Extract data FAT_2_mx_cluster address
			Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 1);
			Temp32.AsByte[2] = 0;
			Temp32.AsByte[3] = 0;

			#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
				if (FAT_2_mx_fat_system == 1)
				{
					Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 2);
					Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN) + 3);
				}
			#endif

			fat_pointer = Temp32.AsLong;
		}

		FCD_FAT160_Write_Byte_To_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN), 0xFF);					//Write end of file marker into new FAT address
		FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 1), 0xFF);

		#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
			if (FAT_2_mx_fat_system == 1)
			{
				FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 2), 0xFF);
				FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 3), 0x0F);
			}
		#endif

		FCD_FAT160_MX_Send_Buffer(fat_address);
		FCD_FAT160_MX_Send_Buffer(fat_address + FAT_2_mx_fat_size);				//Mirror data onto FAT 2

		fat_address = ((fat_address - FAT_2_mx_fat_start) * FAT_2_FATS_PER_SECT) + idx_fat;
		idx_fat = FAT_2_mx_cluster;
		FAT_2_mx_cluster = fat_address;								//Store new FAT_2_mx_cluster address

		fat_address = FAT_2_mx_fat_start;
		while (idx_fat >= FAT_2_FATS_PER_SECT)
		{
			idx_fat = idx_fat - FAT_2_FATS_PER_SECT;
			fat_address = fat_address + 1;
		}
		FCD_FAT160_MX_Get_Buffer(fat_address);

		Temp32.AsLong = FAT_2_mx_cluster;

		FCD_FAT160_Write_Byte_To_Buffer((idx_fat * FAT_2_SECT_ADDR_LEN), Temp32.AsByte[0]);				//Update old FAT address
		FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 1), Temp32.AsByte[1]);

		#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
			if (FAT_2_mx_fat_system == 1)
			{
				FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 2), Temp32.AsByte[2]);
				FCD_FAT160_Write_Byte_To_Buffer(((idx_fat * FAT_2_SECT_ADDR_LEN) + 3), Temp32.AsByte[3]);
			}
		#endif

		FCD_FAT160_MX_Send_Buffer(fat_address);
		FCD_FAT160_MX_Send_Buffer(fat_address + FAT_2_mx_fat_size);				//Mirror data onto FAT 2

		FAT_2_mx_file_sector = FAT_2_mx_file_sector + 1;						//Increment file sector
		FAT_2_mx_current_address = (long) FAT_2_mx_data_start + ((FAT_2_mx_cluster - 2) * FAT_2_mx_sects_per_clust);//Move to next sector in file		BR 06/10 was * 32
		FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);

}

static void FCD_FAT160_MX_Clear_Buffer()
{
	
		MX_SINT16 count;

		for (count = 0; count < 256; count++)
		{
			FAT_2_mx_card_bufferh[count] = 0x00;
			FAT_2_mx_card_bufferl[count] = 0x00;
		}

}

static MX_UINT8 FCD_FAT160_Read_Next_File_Sector()
{
	
		#if (FAT_2_FAT_TYPE == 0)
			MX_UINT16 temp_FAT_2_mx_cluster;
			MX_UINT16 old_FAT_2_mx_cluster;
		#endif
		#if (FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
			MX_UINT32 temp_FAT_2_mx_cluster;
			MX_UINT32 old_FAT_2_mx_cluster;
		#endif

		MX_UINT32 fat_address;
		MX_UINT8 retval;

		MX_Union32 Temp32;

		FAT_2_mx_current_address = FAT_2_mx_current_address + 1;								//Increment address
		if (((FAT_2_mx_current_address - FAT_2_mx_data_start) % FAT_2_mx_sects_per_clust) == 0)		//If end of FAT_2_mx_cluster reached then find next FAT_2_mx_cluster BR 06/10 was % 32
		{
			temp_FAT_2_mx_cluster = FAT_2_mx_cluster;
			fat_address = FAT_2_mx_fat_start;												//Move to start of FAT
			while (temp_FAT_2_mx_cluster >= FAT_2_FATS_PER_SECT)								//256 FAT16 / 128 FAT32 entries per sector
			{
				temp_FAT_2_mx_cluster = temp_FAT_2_mx_cluster - FAT_2_FATS_PER_SECT;
				fat_address = fat_address + 1;										//Increment sector of FAT
			}
			FCD_FAT160_MX_Get_Buffer(fat_address);												//Read FAT sector
			old_FAT_2_mx_cluster = FAT_2_mx_cluster;

			Temp32.AsByte[0] = FCD_FAT160_Read_Byte_From_Buffer(temp_FAT_2_mx_cluster * FAT_2_SECT_ADDR_LEN);	//Extract data FAT_2_mx_cluster address
			Temp32.AsByte[1] = FCD_FAT160_Read_Byte_From_Buffer((temp_FAT_2_mx_cluster * FAT_2_SECT_ADDR_LEN) + 1);
			Temp32.AsByte[2] = 0;
			Temp32.AsByte[3] = 0;

			#if	(FAT_2_FAT_TYPE == 1 || FAT_2_FAT_TYPE == 2)
				if (FAT_2_mx_fat_system == 1)
				{
					Temp32.AsByte[2] = FCD_FAT160_Read_Byte_From_Buffer((temp_FAT_2_mx_cluster * FAT_2_SECT_ADDR_LEN) + 2);
					Temp32.AsByte[3] = FCD_FAT160_Read_Byte_From_Buffer((temp_FAT_2_mx_cluster * FAT_2_SECT_ADDR_LEN) + 3);
				}
			#endif

			FAT_2_mx_cluster = Temp32.AsLong;

			if (FAT_2_mx_cluster == 0 || FAT_2_mx_cluster >= FAT_2_NOT_ADDRESS_MARKER)							//If not an address
			{
				if (FAT_2_mx_cluster > FAT_2_MX_EOF_MARKER)
					retval = MX_ACK_EOF;											//End of file
				if (FAT_2_mx_cluster < FAT_2_MX_EOF_MARKER)
					retval = MX_ERR_RESERVED;										//Reserved FAT_2_mx_cluster
				if (FAT_2_mx_cluster == FAT_2_MX_EOF_MARKER)
					retval = MX_ERR_BAD;											//Bad FAT_2_mx_cluster
				if (FAT_2_mx_cluster == 0)
					retval = MX_ERR_FREE;											//Free FAT_2_mx_cluster - Fat Error

				FAT_2_mx_current_address = FAT_2_mx_current_address - 1;						//Restore address
				FAT_2_mx_cluster = old_FAT_2_mx_cluster;										//Restore FAT_2_mx_cluster
				FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);									//Read sector
				return retval;
			}

			FAT_2_mx_current_address = FAT_2_mx_data_start + ((FAT_2_mx_cluster - 2) * FAT_2_mx_sects_per_clust);			//Move to next sector in file   BR 06/10 was * 32
		}

		FAT_2_mx_file_sector = FAT_2_mx_file_sector + 1;										//Increment file sector

		return FCD_FAT160_MX_Get_Buffer(FAT_2_mx_current_address);									//Read sector

}

static MX_UINT8 FCD_FAT160_MX_Send_Cmd(MX_UINT8 Cmd, MX_UINT32 Addr)
{
	
		MX_UINT8 i, RetVal;
		MX_Union32 Addr32;

		Addr32.AsLong = Addr;

		FC_CAL_Bit_Low ( FAT_2_MX_SPI_FAT_CS_PORT, FAT_2_MX_SPI_FAT_CS_PIN);		//CARD-Enabled

		FAT_2_SPI_Master_Byte(Cmd | 0x40);										//Send Command 0
		FAT_2_SPI_Master_Byte(Addr32.AsByte[3]);								//Arg3
		FAT_2_SPI_Master_Byte(Addr32.AsByte[2]);								//Arg2
		FAT_2_SPI_Master_Byte(Addr32.AsByte[1]);								//Arg1
		FAT_2_SPI_Master_Byte(Addr32.AsByte[0]);								//Arg0
		FAT_2_SPI_Master_Byte(0x95);											//CRC

		i = 9;
		do
		{
			RetVal = FAT_2_SPI_Master_Byte(0xFF);				//Wait for response of 1
			if (RetVal != 0xff) break;
		} while ( --i > 0);

		return RetVal;

}

#include "C:\Program Files\Flowcode(AVR)\v5\CAL\includes.c"

//Macro implementations


int main()
{
	//Initialization
	MCUSR=0x00;


	//Interrupt initialization code
	
	//Loop
	//Loop: While 1
	while (1)
	{

		//Call Component Macro
		//Call Component Macro: status=Init_FAT()
		FCV_STATUS = FCD_FAT160_Init_FAT();

		//Output
		//Output: status -> PORTD
		DDRD = 0xFF;
		PORTD = (FCV_STATUS);

		//Delay
		//Delay: 1 s
		delay_s(1);


	}

	mainendloop: goto mainendloop;
}



