#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

#include "main.h"
#include "mmc_driver.h"
#include "fatfs_mmc.h"

// Registors To read FAT
// Supported FAT16 only

// if you want to drive SD on FAT16 system, you can drive writing only 2 commands as follows
//
// MMC_INIT();
// FATFS_INIT();


unsigned char Sector_Per_Cluster;
unsigned long SectorZero;
unsigned long Beginning_Of_FAT_Sector;
unsigned long Reserved_for_FAT_Sector;
unsigned long Beginning_Of_Dir_Sector;
unsigned long Beginning_Of_Data_Sector;
unsigned long Now_Cluster;


void Get_Sector_Zero(void){
	unsigned int  LP1;
	SectorZero = 0;
	
	do{
		for(LP1=100;LP1!=0;LP1--)SPI_SEND(0xff);					
	}while(MMC_CMD(18,0x00,0x01)!= 0x00);	//end do
	//CMD18=52_(4-byte data address)_01h	
	//-----------------------------
	// read start
	//-----------------------------		
	while(SPI_SEND(0xff) != 0xfe);	//get start token?
	for(LP1=0;LP1<512;LP1++){
		switch(LP1){
			case 454:
				SectorZero = SPI_SEND(0xff);
				break;
			default:
				SPI_SEND(0xff);
				break;
		}// end switch(LP1)
	}	//end for(LP1=0;LP1<512;LP1++)
	SPI_SEND(0xff);		//16-bit CRC
	SPI_SEND(0xff);		//16-bit CRC
	MMC_SEND_STOP();
	
}


void Read_BPB(void)
{
	unsigned int LP1;
	
	do{
		for(LP1=100;LP1!=0;LP1--)SPI_SEND(0xff);					
	}while(MMC_CMD(18,(SectorZero << 9),0x01)!= 0x00);	//end do
	//CMD18=52_(4-byte data address)_01h	
	//-----------------------------
	// read start
	//-----------------------------		
	while(SPI_SEND(0xff) != 0xfe);	//get start token?
	for(LP1=0;LP1<512;LP1++)
	{
		switch(LP1)
		{
			case 13:
				Sector_Per_Cluster = SPI_SEND(0xff);
				break;
			case 14:
				Beginning_Of_FAT_Sector = SPI_SEND(0xff);
				break;
			case 22:
				Reserved_for_FAT_Sector = SPI_SEND(0xff); 
				break;
			default:
				SPI_SEND(0xff);
				break;
		}
		
	}	//end for(LP1=0;LP1<512;LP1++)
	SPI_SEND(0xff);		//16-bit CRC
	SPI_SEND(0xff);		//16-bit CRC
	MMC_SEND_STOP();
	
	Beginning_Of_Dir_Sector = Beginning_Of_FAT_Sector + (Reserved_for_FAT_Sector * 2);
	Beginning_Of_Data_Sector = Beginning_Of_Dir_Sector + 32;
}

unsigned long Get_File_Num(unsigned char Num)
{
	unsigned long File_Length_Sector = 0;
	unsigned int LP1;
	unsigned char LP2;

	unsigned char UUBUF[32];
	if(Num > 16)Num = 16;
	
	do{
		for(LP1=100;LP1!=0;LP1--)SPI_SEND(0xff);					
	}while(MMC_CMD(18,((Beginning_Of_Dir_Sector + SectorZero) << 9),0x01)!= 0x00);	//end do
	//CMD18=52_(4-byte data address)_01h	
	//-----------------------------
	// read start
	//-----------------------------		
	while(SPI_SEND(0xff) != 0xfe);	//get start token?
	for(LP1=0;LP1 < Num;LP1++){
		for(LP2=0;LP2<32;LP2++){
			UUBUF[LP2] = SPI_SEND(0xff);
		}
		if((UUBUF[11]!=0x20)||(UUBUF[0]==0xE5)||(UUBUF[26]==0x00)){//deleted file or folder?
			Num++;
			if(Num > 16)Num = 1;
		}
	}	//end for(LP1=0;LP1<Num;LP1++)
	Now_Cluster = (UUBUF[27]<< 8)|UUBUF[26];
	
	File_Length_Sector = (UUBUF[31]<< 8)|UUBUF[30];
	File_Length_Sector <<= 8;	//bug of C compiler
	File_Length_Sector |= UUBUF[29];
	
	//File_Length_Sector= *(unsigned long *)&UUBUF[31];
	File_Length_Sector >>= 1;	//512byte order
	File_Length_Sector &= 0x007FFFFF;
	MMC_SEND_STOP();
	return(File_Length_Sector);
}


void FATFS_INIT(void)
{
	Get_Sector_Zero();
	Read_BPB();
}