#include "p33FJ256GP710.h"
#include "glcd.h"
#include "uart.h"
#include "timer1.h"
#include "sdcard.h"
#include "fileio.h"
#include "stdlib.h"
#include "ctype.h"
#include "string.h"
#include "stddef.h"
// globals
char FError; // error mail box
DISK* D; // mounting information for default storage device
DISK * mount( void)
{
LBA psize; // number of sectors in partition
LBA firsts; // LBA of first sector inside the first partition
int i;
unsigned char *buffer;
// 0. init the I/Os
initSD();
// 1. check if the card is in the slot
// 2. initialize the card
if ( initMedia())
{
Lcd_printf57(0,1,"ERROR INITMEDIA");
return NULL;
}
// 3. allocate space for a DISK structure
D = (DISK *) malloc(sizeof( DISK));
if ( D == NULL) // report an error
{
Lcd_printf57(0,1,"NOT ALLOCATE DISK");
return NULL;
}
// 4. allocate space for a temp sector buffer
buffer = (unsigned char*) malloc(1024);
if ( buffer == NULL) // report an error
{
Lcd_printf57(0,1,"NOT ALLOCATE BUFF");
free( D);
return NULL;
}
// 5. get the Master Boot Record
if ( !readSECTOR( FO_MBR, buffer))
{
Lcd_printf57(0,1,"ERROR READ SECTOR");
free( D); free( buffer);
return NULL;
}
// 6. check if the MBR sector is valid
// verify the signature word
if (( buffer[ FO_SIGN] != 0x55) ||
( buffer[ FO_SIGN +1] != 0xAA))
{
Lcd_printf57(0,1,"ERROR MBR");
free( D); free( buffer);
return NULL;
}
// Valid Master Boot Record Loaded
// 7. read the number of sectors in partition
psize = ReadL( buffer, FO_FIRST_SIZE);
// 8. check if the partition type is acceptable
i = buffer[ FO_FIRST_TYPE];
switch ( i)
{
case 0x04:
case 0x06:
case 0x0E:
// valid FAT16 options
break;
default:
Lcd_printf57(0,1,"ERROR PARTI TYPE");
free( D); free( buffer);
return NULL;
} // switch
// 9. get the first partition first sector -> Boot Record
// get the 32 bit offset to the first partition
firsts = ReadL( buffer, FO_FIRST_SECT); // assuming FO_MBR == 0
// 10. get the sector loaded (boot record)
if ( !readSECTOR( firsts, buffer))
{
Lcd_printf57(0,1,"ERROR BOOT SECTOR");
free( D); free( buffer);
return NULL;
}
// 11. check if the boot record is valid
// verify the signature word
if (( buffer[ FO_SIGN] != 0x55) ||
( buffer[ FO_SIGN +1] != 0xAA))
{
free( D); free( buffer);
return NULL;
}
// Valid Partition Boot Record Loaded
// get the full partition/drive layout
// 12. determine the size of a cluster
D->sxc = buffer[ BR_SXC];
// this will also act as flag that the disk is mounted
// 13. determine fat, root and data LBAs
// FAT = first sector in partition (boot record) + reserved records
D->fat = firsts + ReadW( buffer, BR_RES);
D->fatsize = ReadW( buffer, BR_FAT_SIZE);
D->fatcopy = buffer[ BR_FAT_CPY];
// 14. ROOT = FAT + (sectors per FAT * copies of FAT)
D->root = D->fat + ( D->fatsize * D->fatcopy);
// 15. MAX ROOT is the maximum number of entries in the root directory
D->maxroot = ReadOddW( buffer, BR_MAX_ROOT) ;
// 16. DATA = ROOT + (MAXIMUM ROOT *32 / 512)
D->data = D->root + ( D->maxroot >> 4); // assuming maxroot % 16 == 0!!!
// 17. max clusters in this partition = (tot sectors - sys sectors )/sxc
D->maxcls = (psize - (D->data - firsts)) / D->sxc;
// 18. free up the temporary buffer
free( buffer);
return D;
} // mount
//----------------------------------------------------------------------
// unmount initializes a DISK structure for FILEIO access
//
void unmount( void)
{
free( D);
} // unmount
//----------------------------------------------------------------------
//
int readDIR( FILE *fp, unsigned e)
// loads current entry sector in file buffer
// returns FAIL/TRUE
{
LBA l;
int r;
// fp->buffer = t;
// Lcd_printf(0,3,"THOAT2");
if(fp->buffer == NULL)
Uart2_send_string("BUFF ERROR");
// load the root sector containing the DIR entry "e"
l = fp->dsk->root + (e >> 4);
// Write_int(0,3,l);
r = readSECTOR( l, fp->buffer);
return (r );
} // readDIR
//----------------------------------------------------------------------
//
unsigned writeDIR( FILE *fp, unsigned entry)
// write current entry sector
// returns FAIL/TRUE
{
int r;
LBA l = fp->dsk->root + (entry >> 4);
// fp->buffer = t;
// write the root sector
r = writeSECTOR( l, fp->buffer);
return (r) ;
} // writeDIR
//----------------------------------------------------------------------
// Find a File entry in current directory
//
unsigned findDIR( FILE *fp)
// fp file structure
// return found/not_found/fail
{
unsigned eCount; // current entry counter
unsigned e; // current entry offset in buffer
int i, a;
DISK *dsk = fp->dsk;
// 1. start from the first entry
eCount = 0;
// load the first sector of root
if ( !readDIR( fp, eCount))
{
return FAIL;
Uart2_send_string("N READ DIR");
}
// Lcd_printf(0,2,"ERROR READ DIR");
// 2. loop until you reach the end or find the file
while ( 1)
{
// 2.0 determine the offset in current buffer
e = (eCount&0xf) * DIR_ESIZE;
// 2.1 read the first char of the file name
a = fp->buffer[ e + DIR_NAME];
// 2.2 terminate if it is empty (end of the list)
if ( a == DIR_EMPTY)
{
return NOT_FOUND;
} // empty entry
// 2.3 skip erased entries if looking for a match
if ( a != DIR_DEL)
{
// 2.3.1 if not VOLume or DIR compare the names
a = fp->buffer[ e + DIR_ATTRIB];
if ( !((a & ATT_DIR) || ( a & ATT_VOL)) )
{
// compare file name and extension
for (i=DIR_NAME; i<DIR_ATTRIB; i++)
{
if ( ( fp->buffer[ e + i]) != ( fp->name[i]))
break; // difference found
}
if ( i == DIR_ATTRIB)
{
// entry found, fill the file structure
fp->entry = eCount; // store entry index
fp->time = ReadW( fp->buffer, e + DIR_TIME);
//Lcd_printf(0,7,"QUAA");
fp->date = ReadW( fp->buffer, e + DIR_DATE);
fp->size = ReadL( fp->buffer, e + DIR_SIZE);
fp->cluster = ReadL( fp->buffer, e + DIR_CLST);
return FOUND;
}
// Lcd_printf(0,7,"READDIR F");
} // not dir nor vol
} // not deleted
// 2.4 get the next entry
eCount++;
if ( (eCount & 0xf) == 0)
{ // load a new sector from the Dir
if ( !readDIR( fp, eCount))
{
return FAIL;
Uart2_send_string("READDIR FAIL");
}
}
// 2.5. exit the loop if reached the end or error
if ( eCount >= dsk->maxroot)
{
return NOT_FOUND; // last entry reached
Uart2_send_string("NOT FOUND DIR");
}
}// while
} // findDIR
//-------------------------------------------------------------