0,0 → 1,1482 |
#include <stdio.h> |
#include <avr/io.h> |
#include "fat16.h" |
#include "sdc.h" |
#include "printf_P.h" |
|
|
//________________________________________________________________________________________________________________________________________ |
// Module name: fat16.c |
// Compiler used: avr-gcc 3.4.5 |
// Last Modifikation: 28.03.2008 |
// Version: 1.25 |
// Authors: Stephan Busker |
// Description: Source files for FAT16 implementation with read and write-access using AVR-Mikrocontrollers |
// Copyright (C) 2007 Stephan Busker |
//........................................................................................................................................ |
// Functions: extern u8 FAT16_Init(void); |
// u8 fopen_(s8 *fname,s8 mode, File *file); |
// void fclose_(File *file); |
// u32 fread_(void *buffer, u32 size, u32 count, File *file); |
// u32 fwrite_(void *buffer, u32 size, u32 count, File *file); |
// s16 fseek_(File *file, s32 offset, s16 origin); |
// s8 fgets_(s8 *string, s16 count, File *file); |
// u8 fputchar_(File *file,s8 c); |
// u8 fputs_(File *file,s8 *string); |
// s8 * fgets(s8 *, s16, File); |
// u8 fexist_(u8*, File *file); |
// u8 mkdir__(s8 *name); |
// u8 chdir__(s8 *name); |
// u8 findfirst_(s8 *fname, Find *item, u8 attribute); |
// u8 findnext_(Find *item); |
// u8 fdelete_(s8 *fname) |
// u8 rmdir_(s8 *dname) |
//........................................................................................................................................ |
// ext. functions: extern u8 SDC_GetSector (u32,u8 *); |
// extern u8 SDC_PutSector (u32,u8 *); |
//........................................................................................................................................ |
// |
// URL: www.Mikro-Control.de |
// mailto: stephan.busker@mikro-control.de |
//________________________________________________________________________________________________________________________________________ |
|
u8 text[80]; |
|
|
//________________________________________________________________________________________________________________________________________ |
// |
// Global variables needed for read- or write-acces to the FAT16- filesystem. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u8 SectorsPerCluster = 0; // how many sectors does a cluster contain? |
u8 FatCopies = 0; // Numbers of copies of the FAT |
u16 PossibleRootEntries = 0; // Possible number of entries in the root directory. |
u16 SectorsPerFat = 0; // how many sectors does a fat16 contain? |
u32 ReservedSectors = 0; // Sectors reserved by the filesystem. |
u32 FirstPartitionSector = 0; // Distance in sectors between the first partition and the master bootrecord. |
u32 FileAllocationTable = 0; // pointer to the first FAT |
u32 RootDirectory = 0; // Pointer to the rootdirectory of the first partition. |
u32 FirstDataCluster = 0; // Pointer to the first cluster containing data (cluster0). |
u32 CWD = 0; // Pointer startcluster to the current working directory |
|
|
struct DirEntry *DirectoryEntry; // Pointer to an entry of the directory. |
struct FatEntry *Fat; // Pointer to an entry of the fat (next clusterposition). |
|
File FilePointer[__MAX_FILES_USED]; // Allocate Memmoryspace for each filepointer used. |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: InitFat16(void); |
// |
// Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdirectory |
// and stores the information in global variables. |
// |
// Returnvalue: The function returns "0" if the filesystem could not be initialized because no partition was found on the disc. |
//________________________________________________________________________________________________________________________________________ |
|
u8 FAT16_Init(void) |
{ |
u8 retvalue = 0; |
u8 cnt = 0; |
struct VBR_Entry *VBR; // Pointer to the VolumeBootRecord. |
struct MBR_Entry *MBR; // Pointer to the masterbootrecord. |
File *file; |
|
for(cnt=0;cnt<__MAX_FILES_USED;cnt++) |
{ |
FilePointer[cnt].state = _UNUSED; // declare the filepointers as unused. |
} |
|
file = &FilePointer[0]; |
|
while((SDC_Init() != 0) && (cnt++<200)); // initialise the sdcard. |
if(cnt <200) //sdcard initialised succesfully |
{ |
SDC_GetSector((u32)_MBR_SECTOR,file->buffer); // Read the MasterBootRecord from mmc. |
MBR = (struct MBR_Entry *) file->buffer; |
FirstPartitionSector = MBR->PartitionEntry1.NoSectorsBeforePartition; |
if((MBR->PartitionEntry1.Type == _FAT16_32_MB_BIOS_Extension) || |
(MBR->PartitionEntry1.Type == _FAT16_ST_32_MB) || |
(MBR->PartitionEntry1.Type == _FAT16_LT_32_MB)) |
{ |
SDC_GetSector(FirstPartitionSector,file->buffer); // Read the volume bootrecord from mmc. |
|
VBR = (struct VBR_Entry *) file->buffer; // Enter the VBR using the structure VBR_Entry. |
SectorsPerCluster = VBR->SectorsPerCluster; // Number of sectors per cluster. Depends on the memorysize of the sd-card. |
FatCopies = VBR->NoFATCopies; // Number of fatcopies. |
PossibleRootEntries = VBR->MaxRootEntries; // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries). |
SectorsPerFat = VBR->SectorsPerFAT; // The number of sectors per FAT. |
ReservedSectors = VBR->ReservedSectors; // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster. |
|
FileAllocationTable = (u32)(FirstPartitionSector + (u32)ReservedSectors); // Calculate the position of the FileAllocationTable. |
RootDirectory = (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies)); // Calculate the position of the Rootdirectory. |
FirstDataCluster = (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4))); // Calculate the position of the first datacluster. |
CWD = RootDirectory; // The actual directory is the rootdirectory. |
retvalue = 1; |
} |
} |
return(retvalue); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: File * fopen_(u8*, u8 *); |
// |
// Description: This function looks for the file in the directory specified by the variable "CWD" of the drive. If the file is found the number of the |
// corrosponding datacluster is returned to main. Only modes 'r' (reading) and 'a' append are implemented yet. |
// |
// Return: 0 = faild to open speicified file |
// 1 = file opened |
//________________________________________________________________________________________________________________________________________ |
|
File * fopen_(s8 *fname, s8 mode) |
{ |
File *file; |
|
file = ReserveFilePointer(); // reserve a filepointer. |
|
if(file != NULL) // A free filepointer was found. |
{ |
file->mode = mode; // mode of fileoperation (read,write) |
|
if(SeekFileInDirectory(fname, file)) // if file was found |
{ |
if(mode == 'a') // open existing file for writing (append data at the end of the file) |
{ |
fseek_(file, 0, SEEK_END); // fseek points to the end of the file |
} |
else if(mode == 'r') |
{ |
return(file); |
} |
else |
{ |
fclose_(file); |
file = NULL; |
} |
|
} |
else |
{ |
if((mode == 'a') || (mode == 'w')) // specified file doesn't exist so create new file for writing data. |
{ |
if(CreateFileInDirectory(fname,file)) // Could an entry for the new file in the rootdirectory be created? |
{ |
return(file); |
} |
else |
{ |
fclose_(file); |
file = NULL; |
} |
} |
} |
} |
return(file); |
} |
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: fflush_(File *file); |
// |
// Description: This function writes the data already in the buffer but not yet written to the file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
s16 fflush_(File *file) |
{ |
u16 time=0; |
u16 date=0; |
|
|
if(file && ((file->mode =='a') || (file->mode =='w'))) |
{ |
if(file->byte_index > 0) // has data been added to the file? |
{ |
SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer);// save the data still in the buffer |
} |
SDC_GetSector((u32)file->directory_sector,file->buffer); // read the directoryentry for this file. |
DirectoryEntry = (struct DirEntry *)file->buffer; |
DirectoryEntry[file->directory_index].size = (u32) file->filesize; |
DirectoryEntry[file->directory_index].time = (u16) time; |
DirectoryEntry[file->directory_index].date = (u16) date; |
SDC_PutSector((u32)file->directory_sector,file->buffer); |
} |
return(0); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: fclose_(File *file); |
// |
// Description: This function closes the open file by writing the remaining data from the buffer to the device and entering the filesize |
// in the directory entry. |
//________________________________________________________________________________________________________________________________________ |
|
void fclose_(File *file) |
{ |
if(file != NULL) |
{ |
fflush_(file); // save buffered data to the disk |
} |
FreeFilePointer(file); // and free the filepointer. |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u32 fread_(void *buffer, s32 size, s32 count, File *file); |
// |
// Description: This function reads count objects of the specified size from the actual position of the file to the specified buffer. |
// |
// Returnvalue: The function returns the number of objects (not bytes) read from the file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u32 fread_(void *buffer, u32 size, u32 count, File *file) |
{ |
u32 object_cnt = 0; // count the number of objects read from the file. |
u32 object_size = 0; // count the number of bytes read from the actual object. |
u8 *buff_pnt = 0; // a pointer to the actual bufferposition. |
u8 success = 1; // no error occured during read operation to the file. |
|
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 * |
|
while((object_cnt < count) && success) |
{ |
object_size = size; |
while((size > 0) && success) |
{ |
*buff_pnt = (u8) fgetchar_(file); // read a byte from the buffer to the opened file. |
buff_pnt++; |
size--; |
} |
if(success) object_cnt++; |
} |
|
return(object_cnt); // return the number of objects succesfully read from the file |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u32 fwrite_(void *buffer, s32 size, s32 count, File *file); |
// |
// Description: This function writes count objects of the specified size from the buffer to the actual positon within the file. |
// |
// Returnvalue: The function returns the number of objects (not bytes) written to the file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u32 fwrite_(void *buffer, u32 size, u32 count, File *file) |
{ |
u32 object_cnt = 0; // count the number of objects written to the file. |
u32 object_size = 0; // count the number of bytes written from the actual object. |
u8 *buff_pnt = 0; // a pointer to the actual bufferposition. |
u8 success = 1; // no error occured during write operation to the file. |
|
buff_pnt = (u8 *) buffer; // cast the void pointer to an u8 * |
|
while((object_cnt < count) && success) |
{ |
object_size = size; |
while((size > 0) && success) |
{ |
success = fputchar_(file, *buff_pnt); // write a byte from the buffer to the opened file. |
buff_pnt++; |
size--; |
} |
if(success) object_cnt++; |
} |
|
return(object_cnt); // return the number of objects succesfully written to the file |
} // (!!!!! objects and not bytes !!!!) |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: s16 fseek_(File *, s32, s16) |
// |
// Description: This function sets the pointer of the stream relative to the position |
// specified by origin (SEEK_SET, SEEK_CUR, SEEK_END). |
// |
//________________________________________________________________________________________________________________________________________ |
|
s16 fseek_(File *file, s32 offset, s16 origin) |
{ |
s32 fposition = 0; |
s16 retvalue = 1; |
u32 temp = 0; |
|
//...................................................... |
if(origin == SEEK_SET) // Fileposition relative to the beginning of the file. |
{ |
fposition = 0; |
} |
//...................................................... |
else if(origin == SEEK_END) // Fileposition relative to the end of the file. |
{ |
fposition = (s32) file->filesize; |
} |
//...................................................... |
else if(origin == SEEK_CUR) // Fileposition relative to the current position of the file. |
{ |
fposition = file->fileposition; |
} |
|
fposition += offset; |
|
if((fposition >= 0) && (fposition <= (s32)file->filesize)) // is the pointer still within the file? |
{ |
retvalue = 0; |
file->sector_index = 0; |
file->byte_index = 0; |
file->fileposition = 0; |
file->cluster_pointer = file->start_cluster; |
|
while(file->fileposition < fposition) |
{ |
file->fileposition++; |
if(file->byte_index < 511) |
{ |
file->byte_index++; |
} |
else |
{ |
file->byte_index=0; // reading at the beginning of new sector. |
file->sector_index++; // continue reading in next sector |
if(file->sector_index >= SectorsPerCluster) // When end of cluster is reached, the next datacluster has to be searched in the FAT. |
{ |
if(file->fileposition < fposition) |
{ |
file->sector_index = 0; // start reading new cluster at first sector of the cluster. |
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster. |
} |
} |
} |
} |
if(file->byte_index) |
{ |
temp = (u32)((u32)file->cluster_pointer + (u32)file->sector_index); |
SDC_GetSector((u32)temp,file->buffer); // FileBuffer will be written at once at the end of the cluster and has to be updated. |
} |
} |
return(retvalue); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: fgetchar_(File *file); |
// |
// Description: This function reads and returns one character from the specified file. |
// |
// Returnvalue: The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF. |
//________________________________________________________________________________________________________________________________________ |
|
s16 fgetchar_(File *file) |
{ |
s16 c = EOF; |
u32 temp1; |
|
if(file->filesize > 0) // wen the end of the file is not reached, get the next character. |
{ |
temp1 = (u32)file->cluster_pointer; // calculate the adress of the next character to be read. |
temp1 += (u32)file->sector_index; |
|
if(file->sector_in_buffer != temp1) // Has the content of the buffer been modified and has to be updated? |
{ |
SDC_GetSector((u32)temp1,file->buffer); // Read the calculated cluster. |
file->sector_in_buffer = (u32)temp1; |
} |
c = (s16) file->buffer[file->byte_index]; |
file->filesize--; // decrement the number of characters available. |
|
if(file->byte_index < 511) // continue reading from this sector until the end of the sector is reached. |
{ |
file->byte_index++; |
} |
else // has the end of an sector been reached-> |
{ |
file->byte_index=0; // continue reading at the beginning - |
file->sector_index++; // of new sector. |
if(file->sector_index >= SectorsPerCluster) // When the end of an cluster is reached, the next datacluster has to be searched in the FAT. |
{ |
file->sector_index = 0; // start reading new cluster at first sector of the cluster. |
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster. |
} |
} |
} |
return(c); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: fputchar_(File *file, s8 *); |
// |
// Description: This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries. |
// |
// Returnvalue: The function returns a value of 0 if the data could not be written. |
//________________________________________________________________________________________________________________________________________ |
|
u8 fputchar_(File *file,s8 c) |
{ |
u32 ul_temp = 0; |
u8 retvalue = 1; |
|
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster |
{ |
file->sector_index = 0; |
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file. |
} |
|
file->buffer[file->byte_index] = c; // write databyte into the buffer. The byte will be written to the device at once |
if(file->filesize == file->fileposition) file->filesize++; // a character has been written to the file so the size is inkremented but only when the character has been added at the end of the file. |
file->fileposition++; // the actual positon within the file. |
// if the buffer contains the complete sectordata. |
if(file->byte_index < 511) // if the end of this sector is not reached yet |
{ |
file->byte_index++; // the next byte will be written to the next byteposition in this sector. |
} |
else // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected. |
{ |
ul_temp = (u32)file->cluster_pointer; |
ul_temp += (u32)file->sector_index; |
|
SDC_PutSector((u32)ul_temp,file->buffer); |
file->byte_index=0; // and the next byte will be written at the beginning of this new sector. |
file->sector_index++; |
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster |
{ |
file->sector_index = 0; |
if(!AppendCluster(file)) retvalue = 0; // append a new and free cluster at the end of the file. |
} |
} |
return(retvalue); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: fputs_(File *file, s8 *string); |
// |
// Description: This function writes a string to the specified file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u8 fputs_(File *file,s8 * string) |
{ |
u8 i=0; |
|
while(string[i] != 0) |
{ |
fputchar_(file,string[i]); |
i++; |
} |
return(0); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: s8 * fgets_(s8 *string, s16 count, File *file) |
// |
// Description: This function reads a string from the file to the specifies string. |
// |
// Returnvalue: A pointer to the string written from the file. |
//________________________________________________________________________________________________________________________________________ |
|
s8 * fgets_(s8 *string, s16 count, File *file) |
{ |
s16 buff_pnt = 0; |
s16 buff_tmp = 0; |
u8 state = 0; // Variable used for a statemachine to recognize the end of a line. |
|
while(count > 1) // read the count-1 characters from the file to the string. |
{ |
buff_tmp = fgetchar_(file); // read a character from the opened file. |
switch(state) |
{ |
case 0: |
if(buff_tmp == 0x0D) state++; |
break; |
|
case 1: |
if(buff_tmp == 0x0A) |
{ |
count = 1; |
} |
state = 0; |
break; |
} |
if(buff_tmp == EOF) {buff_tmp = 0; count = 1;} // is the end of the file reached, terminate the string with zero. |
string[buff_pnt] = (s8) buff_tmp; |
count--; |
buff_pnt++; |
} |
string[buff_pnt] = 0; |
return(string); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 fexist_(u8*, File *file); |
// |
// Description: This function searches the specified file and returns 0 if the file was not found. |
// |
// |
// Return: 0 = file does not exist |
// 1 = file exists |
//________________________________________________________________________________________________________________________________________ |
|
u8 fexist_(s8 *fname) |
{ |
File *file; |
|
file = ReserveFilePointer(); |
|
if(file != NULL) |
{ |
if((file = fopen_(fname,'r'))!= NULL) |
{ |
fclose_(file); |
return(1); |
} |
else |
{ |
return(0); |
} |
} |
else |
{ |
return(0); |
} |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: GetNextCluster(File *file); |
// |
// Description: This function finds the next datacluster of the file specified with File *file. |
// |
// Returnvalue: The function returns "0" if the last cluster has already been reached. |
//________________________________________________________________________________________________________________________________________ |
|
u16 GetNextCluster(File *file) |
{ |
u32 fat_pointer = 0; |
u32 fat_sector_offset = 0; |
u32 ul_tmp = 0; |
u8 retvalue = 0; // no new cluster found yet. |
|
|
if((file->cluster_pointer >= RootDirectory) && (file->cluster_pointer < (RootDirectory + 31))) |
{ // Is the next cluster searched within the rootdirectory and available? |
file->cluster_pointer++; // the rootdirectory is a linear adress space of 32 clusters. |
retvalue = 1; // and the next cluster has been found. |
} |
else if(file->cluster_pointer > (RootDirectory + 31)) // The specified cluster is within the FAT. |
{ |
fat_sector_offset = ((file->cluster_pointer) - (FirstDataCluster)); // Calculate index of actual cluster within the FAT. |
fat_sector_offset /= SectorsPerCluster; // calculate the index of the actual sector within the FAT. |
fat_sector_offset += 2; // In Fat16 clusterpositions have an offset of two. |
fat_pointer = (fat_sector_offset%0x100); // Calculate the sector within the cluster. |
fat_sector_offset = (fat_sector_offset>>8); // and the position within the sector. |
|
SDC_GetSector((u32)(FileAllocationTable + fat_sector_offset),file->buffer); |
file->sector_in_buffer = (FileAllocationTable + fat_sector_offset); // Mark that new sector has been read. |
|
ul_tmp = (u32)file->buffer[((fat_pointer << 1)+1)]; // Read next sector information from calculated clusterposition. |
ul_tmp = (ul_tmp << 8); |
ul_tmp |= (u32)file->buffer[(fat_pointer << 1)]; |
ul_tmp -=2; // next datacluster is clusterposition in fat - 2. |
ul_tmp *= SectorsPerCluster; // calculate sectorposition of new cluster |
ul_tmp += FirstDataCluster; // in relation to first datacluster of the disk. |
|
if(ul_tmp < 0xfff7) // has a new cluster been read or was the end of the fat reached? |
{ |
file->cluster_pointer = (u32) ul_tmp; // continue reading the file at the beginning of new datacluster. |
retvalue = 1; // a new cluster was found. |
} |
} |
return(retvalue); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 FindNextFreeCluster(void) |
// |
// Description: This function looks in the FAT to find the next free datacluster |
// |
// Returnvalue: The function returns the adress of the next free cluster found within the fAT. |
//________________________________________________________________________________________________________________________________________ |
|
u16 FindNextFreeCluster(File *file) |
{ |
u32 fat_pointer = 0; // Pointer to the first sector of the FAT. |
u32 ul_tmp = 0; // temporary variable used to calculate a sectornumber. |
u16 fat_sector_offset = 0; // index to a sector within the FAT. |
u16 fat_entry = 0; // index to an fatentry within the actual sector (256 fatentries are possible within one sector). |
u16 free_cluster = 0; // a pointer to the first sector of the next free cluster. |
|
fat_pointer = (u32) FileAllocationTable; // start searching for empty cluster at the beginning of the fat. |
// if the end of the fat is not reached yet and no free cluster has been found |
while((fat_sector_offset < SectorsPerFat) && (!free_cluster)) |
{ |
ul_tmp = (u32) ((u32)fat_pointer + (u32)fat_sector_offset); |
SDC_GetSector((u32)ul_tmp,file->buffer); // read next sector of FAT. |
file->sector_in_buffer = ul_tmp; // remember the number of the sector in FileBuffer. |
Fat = (struct FatEntry *)file->buffer; |
for(fat_entry=0;fat_entry<256;fat_entry++) // look for an free cluster at all entries in this sector of the fat. |
{ |
if(Fat[fat_entry].next_cluster == 0x0000) // empty cluster found!! |
{ |
Fat[fat_entry].next_cluster = 0xffff; // mark this fat-entry as used and save it to the device. |
SDC_PutSector((u32)file->sector_in_buffer,file->buffer); |
free_cluster = fat_entry; // the relative position of the free cluster found in this sector of the FAT. |
free_cluster += (fat_sector_offset << 8); // calculate the absolute position of the free cluster in the FAT; |
fat_entry = 256; // terminate the search for a free cluster in this sector. |
} |
} |
fat_sector_offset++; |
} |
return(free_cluster); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 AppendCluster(File *file); |
// |
// Description: This function finds the next free datacluster on the disk and appends it to the specified file. |
// |
// Returnvalue: This funktion returns 1 if a cluster was appended to the specified file. |
//________________________________________________________________________________________________________________________________________ |
|
u8 AppendCluster(File *file) |
{ |
u16 free_cluster = 0; |
u32 fat_pointer = 0; |
u8 retvalue = 0; |
|
free_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk. |
if(free_cluster) retvalue = 1; // A free cluster was found and can be added to the end of the file. |
fat_pointer = FileAllocationTable; // Set Pointer to the beginnig of the FAT. |
fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8); // find the sector in the FAT with 256 entries per sector. |
|
SDC_GetSector(fat_pointer,file->buffer); |
Fat = (struct FatEntry *)file->buffer; |
Fat[GetFatSectorIndex(file)].next_cluster = free_cluster; // append the free cluster to the end of the file in the FAT. |
SDC_PutSector((u32)fat_pointer,file->buffer); // save the modified sector to the FAT. |
|
fat_pointer = (u32)free_cluster; |
fat_pointer -= 2; |
fat_pointer *= SectorsPerCluster; |
fat_pointer += FirstDataCluster; |
|
file->cluster_pointer = fat_pointer; // continue wrtiting to the file in the new and free datacluster. |
return(retvalue); // return 1 when a new cluster was appended to the file |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: void DeleteClusterChain(u16 startcluster); |
// |
// Description: This function frees all the clusters used for file from the fat. |
// |
// Returnvalue: none |
//________________________________________________________________________________________________________________________________________ |
|
void DeleteClusterChain(u16 startcluster) |
{ |
u16 fat_index = 0; |
u16 fat_sector_offset = 0; |
u32 sector_in_buffer = 0; |
u32 ul_temp = 0; |
u8 buffer[512]; |
|
fat_index = (startcluster % 0x100); // Calculate the sector within the cluster. |
fat_sector_offset = (startcluster >> 8); // and the position within the sector. |
ul_temp = (u32)(FileAllocationTable + fat_sector_offset); |
|
|
do |
{ |
if(sector_in_buffer != ul_temp) |
{ |
sector_in_buffer = ul_temp; |
SDC_GetSector(ul_temp,buffer); |
} |
Fat = (struct FatEntry *)buffer; |
|
startcluster = Fat[fat_index].next_cluster; |
Fat[fat_index].next_cluster = 0x0000; // free the cluster within the fat. |
|
fat_index = (startcluster % 0x100); // Calculate the sector within the cluster. |
fat_sector_offset = (startcluster >> 8); // and the position within the sector. |
ul_temp = (u32)(FileAllocationTable + fat_sector_offset); |
if((sector_in_buffer != ul_temp) || (startcluster == 0xffff)) |
{ |
SDC_PutSector(sector_in_buffer,buffer); |
} |
} |
while(startcluster != 0xffff); // last cluster has been deleted. |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 GetFatClusterIndex(File *file); |
// |
// Description: This function returns the clusterindex of the cluster specified by file->cluster_pointer of the specified file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u16 GetFatClusterOffset(File *file) |
{ |
u32 fat_sector_offset = 0; |
|
fat_sector_offset = ((file->cluster_pointer) - (FirstDataCluster)); // Calculate index of actual cluster in FAT. |
fat_sector_offset /= SectorsPerCluster; |
fat_sector_offset += 2; // In Fat16 clusterpositions have an offset of two. |
|
return((u16)fat_sector_offset); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 GetFatSectorIndex(File *file); |
// |
// Description: This function returns the sectorindex of the cluster specified by file->cluster_pointer of the specified file. |
// |
//________________________________________________________________________________________________________________________________________ |
|
u16 GetFatSectorIndex(File *file) |
{ |
u16 fat_pointer = 0; |
|
fat_pointer = GetFatClusterOffset(file); |
fat_pointer = fat_pointer % 0x100; // Calculate the clusterposition in the fat |
|
return(fat_pointer); |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 CreateFileInDirectory(u8 *, File *) |
// |
// Description: This function looks for the next free position in the directory and creates an entry. The type of an directoryentry is |
// specified by the attribute. |
// bit0: unused |
// bit1: archive |
// bit2: read_only |
// bit3: system |
// bit4: directory |
// bit5: volume |
//________________________________________________________________________________________________________________________________________ |
|
u8 CreateFileInDirectory(s8 *fname, File *file) |
{ |
u16 rootentry = 0; // index to an entry in the rootdirectory. |
u16 cnt_enries_searched = 0; // count the number of rootentries which have been searched already. |
u8 i = 0; |
u16 sector_offset = 0; // index to the sector of the Rootentry which is searched momentarily |
u8 retvalue = 0; |
u32 cluster_temp = 0; |
u16 cluster = 0; |
s8 name[11] = " "; |
|
SeperateFileName(fname,name); |
|
cluster_temp = (u32)FindNextFreeCluster(file); // the next free cluster on the disk. |
|
if(cluster_temp) // if a free cluster is available: |
{ |
cluster = (u16)cluster_temp; // remember the index of the free datacluster found for the directory entry. |
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved. |
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster. |
file->start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster. |
file->cluster_pointer = file->start_cluster; // start reading the file with the first sector of the first datacluster. |
|
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory. |
do |
{ // search the next 16 rootentries in this sector of the roordirectory. |
rootentry=0; |
SDC_GetSector((u32)(CWD + sector_offset),file->buffer); // Read the Rootdirectory. |
DirectoryEntry = (struct DirEntry *)file->buffer; |
while((rootentry<16) && (!retvalue)) |
{ |
if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found |
{ |
for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = name[i]; // Kopie the filename and the file extension to the directoryentry. |
DirectoryEntry[rootentry].attribute = _FILE; // Set the fileattribute to archive to reserve the directoryentry. |
DirectoryEntry[rootentry].startcluster = cluster; // copy the location of the first datacluster to the directoryentry. |
DirectoryEntry[rootentry].size = 0; // the new createted file has no content yet. |
file->directory_sector = (u32) (CWD + sector_offset); |
file->directory_index = (u8) rootentry; |
retvalue = 1; |
SDC_PutSector((u32)(CWD + sector_offset),file->buffer); |
} |
rootentry++; |
cnt_enries_searched++; |
} |
if(!retvalue) // file not found in this sector so take next sector. |
{ |
rootentry = 0; |
sector_offset++; |
} |
} |
while((cnt_enries_searched< PossibleRootEntries) && (!retvalue)); |
|
} |
return(retvalue); // return 1 if file has been created otherwise return 0. |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 SeekFileInDirectory(s8 *fname, File *) |
// |
// Description: this function searches all possible entries withint the actual directory for the specified object. |
// |
// Returnvalue: This function returns 1 if the directoryentry specified was found. |
//________________________________________________________________________________________________________________________________________ |
|
u8 SeekFileInDirectory(s8 *fname, File *file) |
{ |
u16 rootentry=0; |
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result. |
u8 i=0; |
u8 retvalue = 0; |
u32 cluster_temp = 0; |
s8 name[11] = " "; |
|
SeperateFileName(fname,name); |
|
file->cluster_pointer = CWD; // start looking for the file in the actual directory. |
|
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory. |
do |
{ // search the next 16 rootentries in this sector of the roordirectory. |
rootentry=0; |
SDC_GetSector((u32) file->cluster_pointer,file->buffer); // Read the Rootdirectory. |
DirectoryEntry = (struct DirEntry *)file->buffer; |
|
while((!retvalue)&&(rootentry<16)) |
{ |
i=0; |
if(DirectoryEntry[rootentry].name[0] != 0xe5) // ignore deleted items. |
{ |
while((i<=10)&&(DirectoryEntry[rootentry].name[i] == name[i])) |
{ |
i++; |
} |
} |
|
if((i==11) && (DirectoryEntry[rootentry].attribute & _FILE)) // entry found!! -> reading startcluster of entry from offset 26. |
{ |
cluster_temp = (u32)DirectoryEntry[rootentry].startcluster; |
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved. |
cluster_temp *= (u32)SectorsPerCluster; // Calculate positon of first cluster. |
file->start_cluster = (FirstDataCluster + cluster_temp); |
file->directory_sector = (u32) file->cluster_pointer; |
file->cluster_pointer = file->start_cluster; // start reading the file with the first cluster. |
file->filesize = (u32) DirectoryEntry[rootentry].size; |
file->directory_index = (u8) rootentry; |
retvalue = 1; |
} |
rootentry++; |
} |
if(!retvalue) // file not found in this sector so take next sector. |
{ |
end_of_directory_not_reached = GetNextCluster(file); |
} |
} |
while((end_of_directory_not_reached) && (!retvalue)); |
return(retvalue); |
} |
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: void SeperateFileName(u8*); |
// |
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST TXT'); |
// |
//________________________________________________________________________________________________________________________________________ |
|
void SeperateFileName(s8 *fname, s8 *name) |
{ |
u8 readpointer = 0; |
u8 writepointer = 0; |
u8 attribute = 1; |
u8 i = 0; |
|
|
while((writepointer<=10) && (fname[readpointer]!=0)) // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute. |
{ // the filename in the rootdirectory is in the format "TEST TXT" without the dot. |
if(fname[readpointer]=='.') // seperating filename and attribute. |
{ |
if(attribute) // is the filename "." or ".." ? |
{ |
name[writepointer] = fname[readpointer]; |
readpointer++; |
writepointer++; |
} |
else |
{ |
if(fname[(readpointer-1)] != '*') |
{ |
for(i=writepointer;i<8;i++) |
{ |
name[i] = ' '; |
} |
} |
readpointer++; |
writepointer = 8; |
} |
} |
else if(fname[readpointer] == '*') // wildcard found within the filename + extension. |
{ |
if(writepointer < 8) // in extension. |
{ |
readpointer++; |
writepointer = 8; |
} |
else // in filename. |
{ |
writepointer = 11; // jump to the end of the string to terminate this function. |
} |
attribute = 0; |
} |
else |
{ |
if((fname[readpointer]>96) && (fname[readpointer]<123)) |
{ |
name[writepointer]=(fname[readpointer] - 32); // all characters must be upper case. |
} |
else |
{ |
name[writepointer]=fname[readpointer]; |
} |
readpointer++; |
writepointer++; |
attribute = 0; |
} |
} |
} |
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: File * ReserveFilePointer_(void); |
// |
// Description: This function looks for a free filepointer and reserves it. |
// |
// |
// Return: NULL = faild to reserve a filepointer |
// otherwise filepointer |
//________________________________________________________________________________________________________________________________________ |
|
File * ReserveFilePointer(void) |
{ |
File *file; |
file = NULL; |
u8 temp; |
|
for(temp = 0;temp<__MAX_FILES_USED;temp++) |
{ |
if(FilePointer[temp].state == _UNUSED) // free filepointer found? |
{ |
file = &FilePointer[temp]; |
FilePointer[temp].state = _USED; // mark as used. |
FilePointer[temp].mode = 0; // type of access (read/write) not defined yet. |
FilePointer[temp].start_cluster = 0; // Sectorpointer to the first sector of the first datacluster of the file. |
FilePointer[temp].cluster_pointer = 0; // Pointer to the cluster which is edited at the moment. |
FilePointer[temp].sector_index = 0; // The sector which is edited at the moment (cluster_pointer + sector_index). |
FilePointer[temp].byte_index = 0; // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index). |
FilePointer[temp].filesize = 0; // the size of the opend file in bytes. |
FilePointer[temp].fileposition = 0; // pointer to a character within the file 0 < fileposition < filesize |
FilePointer[temp].sector_in_buffer = 0; // the last sector read, wich is still in the sectorbuffer. |
FilePointer[temp].directory_sector = 0; // the sectorposition where the directoryentry has been made. |
FilePointer[temp].directory_index = 0; // the index to the directoryentry within the specified sector. |
FilePointer[temp].attribute = 0; // the attribute of the file opened. |
break; |
} |
} |
return(file); |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: void FreeFilePointer_(File *); |
// |
// Description: This function free's the filepointer by marking it as unused. |
// |
// |
// Return: none |
// |
//________________________________________________________________________________________________________________________________________ |
|
void FreeFilePointer(File *file) |
{ |
u8 cnt = 0; |
|
for(cnt=0;cnt<__MAX_FILES_USED;cnt++) // Is the filepointeradress vaild? |
{ |
if(&FilePointer[cnt] == file) // filepointer found therefore it must be valid |
{ |
FilePointer[cnt].state = _UNUSED; // and can be marked as unused. |
} |
} |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: void DelteDirectoryEntry(Find *) |
// |
// Description: This function deletes the directoryentry of the specified item. |
// |
// |
// returnvalue: 1 if the directory could be created. |
//________________________________________________________________________________________________________________________________________ |
|
void DeleteDirectoryEntry(Find *item) |
{ |
u8 buffer[512]; |
|
|
SDC_GetSector((u32) item->cluster_pointer,buffer); // Read the Rootdirectory. |
DirectoryEntry = (struct DirEntry *)buffer; |
|
DirectoryEntry[(item->directory_index)-1].attribute = 0; // free the directoryentry. |
DirectoryEntry[(item->directory_index)-1].name[0] = 0xE5; // free the directoryentry. |
SDC_PutSector((u32) item->cluster_pointer,buffer); // Read the Rootdirectory. |
} |
|
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 CreateSubDirectory(u8 *) |
// |
// Description: This function creates an directory within the directory specified by CWD |
// |
// |
// returnvalue: 1 if the directory could be created. |
//________________________________________________________________________________________________________________________________________ |
|
u8 CreateSubDirectory(s8 *fname) |
{ |
u16 index = 0; // index to an entry in the rootdirectory. |
u16 cnt_entries_searched = 0; // count the number of rootentries which have been searched already. |
u16 i = 0; |
u16 sector_offset = 0; // index to the sector of the entry which is searched momentarily |
u8 retvalue = 0; |
u32 cluster_temp = 0; |
u16 cluster = 0; |
File file; |
u8 name[11] = {" "}; |
|
SeperateFileName(fname,name); |
cluster_temp = (u32)FindNextFreeCluster(&file); // the next free cluster on the disk. |
|
if(cluster_temp) // if a free cluster is available: |
{ |
cluster = (u16)cluster_temp; // remember the index of the free datacluster found for the directory entry. |
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved. |
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster. |
file.start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster. |
file.cluster_pointer = file.start_cluster; // start reading the file with the first sector of the first datacluster. |
|
// -Initialise new cluster to zero-------------------------------------------------------- |
for(i=0;i<512;i++) |
{ |
file.buffer[i] = 0; // initialise buffer to zero |
} |
for(sector_offset=0;sector_offset<SectorsPerCluster;sector_offset++) // initialise all sectors of new cluster with buffer. |
{ |
SDC_PutSector((u32)(file.start_cluster + sector_offset),file.buffer); // save the initialised sector to the card. |
} |
// -Create directoryentry "." ------------------------------------------------------------- |
DirectoryEntry = (struct DirEntry *)file.buffer; |
DirectoryEntry[0].name[0] = '.'; |
DirectoryEntry[0].attribute = _DIRECTORY; |
DirectoryEntry[0].startcluster = cluster; |
// -Create directoryentry "." ------------------------------------------------------------- |
DirectoryEntry[1].name[0] = '.'; |
DirectoryEntry[1].name[1] = '.'; |
DirectoryEntry[1].attribute = _DIRECTORY; |
if(CWD == RootDirectory) |
{ |
DirectoryEntry[1].startcluster = 0; |
} |
else |
{ |
cluster_temp = (CWD - FirstDataCluster); |
cluster_temp /= SectorsPerCluster; |
cluster_temp -= 2; |
DirectoryEntry[1].startcluster = (u16) cluster_temp; |
} |
SDC_PutSector((u32) file.start_cluster,file.buffer); // save the initialised sector to the card. |
// -create directoryentry within the cwd -------------------------------------------------- |
sector_offset = 0; |
cnt_entries_searched = 0; |
do |
{ // search the next 16 rootentries in this sector of the roordirectory. |
index=0; |
SDC_GetSector((u32)(CWD + sector_offset),file.buffer); // Read the actual directory. |
DirectoryEntry = (struct DirEntry *)file.buffer; |
while((index<16) && (!retvalue)) |
{ |
if((DirectoryEntry[index].attribute == 0) || (DirectoryEntry[index].attribute == 0xE5)) // empty directory entry found |
{ |
for(i=0;i<11;i++) DirectoryEntry[index].name[i] = name[i]; // Kopie the filename and the file extension to the directoryentry. |
DirectoryEntry[index].attribute = _DIRECTORY; // Set the fileattribute to archive to reserve the directoryentry. |
DirectoryEntry[index].startcluster = cluster; // copy the location of the first datacluster to the directoryentry. |
DirectoryEntry[index].size = 0; // the new createted file has no content yet. |
file.directory_sector = (u32) (CWD + sector_offset); |
file.directory_index = (u8) index; |
retvalue = 1; |
SDC_PutSector((u32)(CWD + sector_offset),file.buffer); |
} |
index++; |
cnt_entries_searched++; |
} |
if(!retvalue) // file not found in this sector so take next sector. |
{ |
index = 0; |
sector_offset++; |
} |
} |
while((cnt_entries_searched< PossibleRootEntries) && (!retvalue)); |
|
} |
return(retvalue); // return 1 if file has been created otherwise return 0. |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u16 SeekSubDirectory(s8 *fname) |
// |
// Description: looks for the specified directory within the CWD. |
// |
// Returnvalue: If the specified directory was found the startcluster is returned. otherwise 0. |
//________________________________________________________________________________________________________________________________________ |
|
u16 SeekSubDirectory(s8 *fname) |
{ |
u16 index = 0; |
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result. |
u8 i = 0; |
u16 cluster_temp = 0; |
s8 name[11] = " "; |
File file; |
|
SeperateFileName(fname,name); |
|
file.cluster_pointer = CWD; // start looking for the file in the actual directory. |
file.start_cluster = CWD; // start looking for the file in the actual directory. |
|
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory. |
do |
{ // search the next 16 rootentries in this sector of the roordirectory. |
index=0; |
SDC_GetSector((u32) file.cluster_pointer,file.buffer); // Read the Rootdirectory. |
DirectoryEntry = (struct DirEntry *)file.buffer; |
|
while((!cluster_temp)&&(index<16)) |
{ |
i=0; |
if(DirectoryEntry[index].name[0] != 0xe5) // ignore deleted items. |
{ |
while((i<=10)&&(DirectoryEntry[index].name[i] == name[i])) |
{ |
i++; |
} |
} |
|
if((i==11) && (DirectoryEntry[index].attribute & _DIRECTORY)) // entry found!! -> reading startcluster of entry from offset 26. |
{ |
cluster_temp = (u16)DirectoryEntry[index].startcluster; |
} |
index++; |
} |
if(!cluster_temp) // file not found in this sector so take next sector. |
{ |
end_of_directory_not_reached = GetNextCluster(&file); |
} |
} |
while((end_of_directory_not_reached) && (!cluster_temp)); |
return(cluster_temp); |
} |
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 mkdir_(u8 *) |
// |
// Description: This function checks if the directory to be created already exists. If not the directory will be created. |
// |
// |
// returnvalue: 1 if the directory could be created. |
//________________________________________________________________________________________________________________________________________ |
|
u8 mkdir_(s8 *fname) |
{ |
u8 retvalue = 0; |
|
retvalue = SeekSubDirectory(fname); // check wether the specified directory already exists. |
|
if(!retvalue) |
{ |
CreateSubDirectory(fname); // if directory doesn't exist, create it. |
retvalue = 1; |
} |
else |
{ |
retvalue = 0; |
} |
|
return(retvalue); |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 chdir_(u8 *) |
// |
// Description: This function changes the CWD to the directory specified. |
// |
// |
// returnvalue: 1 if the directory could be changed. |
//________________________________________________________________________________________________________________________________________ |
|
u8 chdir_(s8 *fname) |
{ |
u8 retvalue = 0; |
u8 name[11] = {" "}; |
|
u32 ultemp = 0; |
|
SeperateFileName(fname,name); |
|
ultemp = (u32)SeekSubDirectory(name); |
if(ultemp >= 2) |
{ |
ultemp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved. |
ultemp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster. |
ultemp += FirstDataCluster; |
CWD = ultemp; |
retvalue = 1; |
} |
else |
{ |
CWD = RootDirectory; |
retvalue = 1; |
} |
|
return(retvalue); |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 FindItem(s8 *fname, Find *) |
// |
// Description: finds an item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered. |
// |
// Returnvalue: If an item was found this function returns '1' else '0'. |
//________________________________________________________________________________________________________________________________________ |
|
u8 FindItem(Find *item) |
{ |
u16 index = 0; |
u16 end_of_directory_not_reached = 0; // the directory has been read completely without a result. |
u8 i = 0; |
u8 readpointer = 0; |
u8 writepointer = 0; |
u8 retvalue = 0; |
File file; |
|
|
file.cluster_pointer = item->cluster_pointer; |
file.start_cluster = item->cluster_pointer; |
index = item->directory_index; |
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory. |
do |
{ // search the next 16 rootentries in this sector of the roordirectory. |
SDC_GetSector((u32) file.cluster_pointer,file.buffer); // Read the Rootdirectory. |
DirectoryEntry = (struct DirEntry *)file.buffer; |
|
while((!retvalue)&&(index<16)) |
{ |
i=0; |
if(DirectoryEntry[index].name[0] != 0xe5) // ignore deleted items. |
{ |
while((i<=10)&&((DirectoryEntry[index].name[i] == item->searchstring[i]) || (item->searchstring[i]=='*') || item->searchstring[i]=='?')) |
{ |
i++; |
} |
} |
|
if((i==11) && (DirectoryEntry[index].attribute & item->attribute)) |
{ |
for(readpointer=0;readpointer<=10;readpointer++) |
{ |
if(DirectoryEntry[index].name[readpointer] != ' ') |
{ |
item->name[writepointer] = DirectoryEntry[index].name[readpointer]; // copy the name of the item found to the find_structure. |
writepointer++; |
} |
else if((readpointer==7) && (DirectoryEntry[index].attribute == _FILE)) // if the item found is a file |
{ |
if(DirectoryEntry[index].name[readpointer] != ' ') |
{ |
item->name[writepointer] = DirectoryEntry[index].name[readpointer]; // copy the name of the item found to the find_structure. |
writepointer++; |
} |
item->name[writepointer] = '.'; // then seperate the name and the extension by a '.' at index 8. |
writepointer++; |
} |
} |
item->startcluster = (u16)DirectoryEntry[index].startcluster; |
item->directory_index = ++index; |
item->cluster_pointer = file.cluster_pointer; |
retvalue = 1; |
} |
index++; |
} |
if(!retvalue) // file not found in this sector so take next sector. |
{ |
end_of_directory_not_reached = GetNextCluster(&file); |
} |
index = 0; |
} |
while((end_of_directory_not_reached) && (!retvalue)); |
|
return(retvalue); |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 findfirst(s8 *fname, Find *) |
// |
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered. |
// |
// Returnvalue: If an item was found this function returns '1' else '0'. |
//________________________________________________________________________________________________________________________________________ |
|
u8 findfirst_(s8 *fname, Find *item, u8 attribute) |
{ |
u8 retvalue = 0; |
u8 i = 0; |
|
for(i=0;i<=11;i++) |
{ |
item->searchstring[i] = '*'; // initialise the searchstring with wildcards. |
item->name[i] = 0; |
} |
|
SeperateFileName(fname,item->searchstring); |
|
item->cluster_pointer = CWD; // findfirst_ starts at the beginning of the cwd. |
item->directory_index = 0; |
item->attribute = attribute; |
|
retvalue = FindItem(item); |
|
return(retvalue); |
} |
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 findnext(Find *) |
// |
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered. |
// |
// Returnvalue: If an item was found this function returns '1' else '0'. |
//________________________________________________________________________________________________________________________________________ |
|
|
u8 findnext_(Find *item) |
{ |
u8 retvalue = 0; |
u8 i = 0; |
|
for(i=0;i<=11;i++) |
{ |
item->name[i] = 0; |
} |
|
retvalue = FindItem(item); |
|
return(retvalue); |
} |
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 fdelete(s8 *fname) |
// |
// Description: Deletes the file specified by fname. |
// |
// Returnvalue: |
//________________________________________________________________________________________________________________________________________ |
|
|
u8 fdelete_(s8 *fname) |
{ |
u8 retvalue = 0; |
Find item; |
|
printf("\n\rDeleting file"); |
retvalue = findfirst_(fname,&item, _FILE); // look for the item to be deleted. |
|
if(retvalue); // item found? |
{ |
printf("\n\r"); |
printf("%s", item.name); |
|
DeleteClusterChain(item.startcluster); // delete all fatentries of the item. |
DeleteDirectoryEntry(&item); // free the directoryentry. |
|
do |
{ |
printf("\n\r"); |
printf("%s", item.name); |
retvalue = findnext_(&item); |
if(retvalue) |
{ |
DeleteClusterChain(item.startcluster); // delete all fatentries of the item. |
DeleteDirectoryEntry(&item); // free the directoryentry. |
} |
} |
while(retvalue); |
} |
|
printf("\n\rDone"); |
|
return(retvalue); |
} |
|
|
|
//________________________________________________________________________________________________________________________________________ |
// Funtion: u8 rmdir(s8 *fname) |
// |
// Description: Deletes the directory specified by dname. |
// |
// Returnvalue: |
//________________________________________________________________________________________________________________________________________ |
|
|
u8 rmdir_(s8 *dname) |
{ |
u8 retvalue = 0; |
Find item; |
|
printf("\n\rDeleting folder"); |
retvalue = findfirst_(dname,&item, _DIRECTORY); // look for the item to be deleted. |
|
if(retvalue); // item found? |
{ |
printf("\n\r"); |
printf("%s", item.name); |
|
DeleteClusterChain(item.startcluster); // delete all fatentries of the item. |
DeleteDirectoryEntry(&item); // free the directoryentry. |
|
do |
{ |
printf("\n\r"); |
printf("%s", item.name); |
retvalue = findnext_(&item); |
if(retvalue) |
{ |
DeleteClusterChain(item.startcluster); // delete all fatentries of the item. |
DeleteDirectoryEntry(&item); // free the directoryentry. |
} |
} |
while(retvalue); |
} |
|
printf("\n\rDone"); |
|
return(retvalue); |
} |
|