Subversion Repositories Projects

Rev

Rev 231 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 231 Rev 297
Line 1... Line 1...
1
#include <stdio.h>
1
#include <string.h>
-
 
2
#include "printf_P.h"
2
#include <avr/io.h>
3
#include "timer0.h"
3
#include "fat16.h"
4
#include "fat16.h"
4
#include "sdc.h"
5
#include "sdc.h"
5
#include "printf_P.h"
6
#include "uart1.h"
Line 86... Line 253...
86
 
253
        File_t * File = 0;
87
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)
254
        for(i = 0; i < FILE_MAX_OPEN; i++)
88
        {
-
 
89
                FilePointer[cnt].state = _UNUSED;                                                               // declare the filepointers as unused.
-
 
90
        }
-
 
91
 
-
 
92
        file = &FilePointer[0];
-
 
93
 
-
 
94
        while((SDC_Init() != 0) && (cnt++<200));                                        // initialise the sdcard.
255
        {
95
        if(cnt <200)                                                                                            //sdcard initialised succesfully
-
 
96
        {
-
 
97
                SDC_GetSector((u32)_MBR_SECTOR,file->buffer);                   // Read the MasterBootRecord from mmc.
-
 
98
                MBR = (struct MBR_Entry *) file->buffer;
-
 
99
                FirstPartitionSector = MBR->PartitionEntry1.NoSectorsBeforePartition;
-
 
100
                if((MBR->PartitionEntry1.Type == _FAT16_32_MB_BIOS_Extension) ||
-
 
101
                   (MBR->PartitionEntry1.Type == _FAT16_ST_32_MB) ||
-
 
102
                   (MBR->PartitionEntry1.Type == _FAT16_LT_32_MB))
-
 
103
                {
-
 
104
                        SDC_GetSector(FirstPartitionSector,file->buffer);               // Read the volume bootrecord from mmc.
-
 
105
 
-
 
106
                        VBR = (struct VBR_Entry *) file->buffer;                                        // Enter the VBR using the structure VBR_Entry.
256
                if(FilePointer[i].State == FSTATE_UNUSED)               // found an unused one
107
                        SectorsPerCluster       = VBR->SectorsPerCluster;                       // Number of sectors per cluster. Depends on the memorysize of the sd-card.
-
 
108
                        FatCopies                       = VBR->NoFATCopies;                                     // Number of fatcopies.
257
                {
109
                        PossibleRootEntries = VBR->MaxRootEntries;                              // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
-
 
110
                        SectorsPerFat           = VBR->SectorsPerFAT;                           // The number of sectors per FAT.
-
 
111
                        ReservedSectors         = VBR->ReservedSectors;                         // calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
-
 
112
 
-
 
113
                        FileAllocationTable     =   (u32)(FirstPartitionSector + (u32)ReservedSectors);                                                 // Calculate the position of the FileAllocationTable.
-
 
114
                        RootDirectory           =   (u32)((u32)FileAllocationTable + (u32)((u32)SectorsPerFat*(u32)FatCopies)); // Calculate the position of the Rootdirectory.
-
 
115
                        FirstDataCluster        =   (u32)((u32)RootDirectory + ((u32)(PossibleRootEntries>>4)));                                        // Calculate the position of the first datacluster.
258
                        File = &FilePointer[i];                                         // set pointer to that entry
116
                        CWD                                     =       RootDirectory;                                                                                                                                  // The actual directory is the rootdirectory.
259
                        FilePointer[i].State = FSTATE_USED;                     // mark it as used
117
                        retvalue = 1;
260
                        break;
118
                }
261
                }
119
        }
262
        }
Line 120... Line 263...
120
        return(retvalue);
263
        return(File);
121
}
264
}
122
 
-
 
123
//________________________________________________________________________________________________________________________________________
265
 
124
// Funtion:     File * fopen_(u8*, u8 *);
266
/****************************************************************************************************************************************/
125
//
-
 
126
// 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
267
/*      Function:               UnlockFilePointer(file_t *);                                                                                                                                                                            */
127
//                              corrosponding datacluster is returned to main. Only modes 'r' (reading) and 'a' append are implemented yet.
268
/*                                                                                                                                                                                                                                                                              */
128
//
269
/*      Description:    This function trys to unlock a file pointer.                                                                                                                                            */
129
//      Return:         0 = faild to open speicified file
-
 
130
//                              1 = file opened
270
/*                                                                                                                                                                                                                                                                              */
131
//________________________________________________________________________________________________________________________________________
271
/*      Returnvalue:    Returns 1 if file pointer was freed else 0.                                                                                                                                                     */
132
 
272
/****************************************************************************************************************************************/
133
File * fopen_(s8 *fname, s8 mode)
-
 
-
 
273
uint8_t UnlockFilePointer(File_t * file)
134
{
274
{
135
        File *file;
275
        uint8_t cnt;
136
 
276
        if(file == NULL) return(0);
137
        file = ReserveFilePointer();                                                                                                    // reserve a filepointer.
277
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
-
 
278
        {
-
 
279
                if(&FilePointer[cnt] == file)                                           // filepointer to be freed found?
-
 
280
                {
-
 
281
                        file->State = FSTATE_UNUSED;
-
 
282
                        file->FirstSectorOfFirstCluster = 0;                    // Sectorpointer to the first sector of the first datacluster of the file.
-
 
283
                        file->FirstSectorOfCurrCluster  = 0;
138
 
284
                        file->SectorOfCurrCluster               = 0;                    // Pointer to the cluster which is edited at the moment.
-
 
285
                        file->SectorOfCurrCluster               = 0;                    // The sector which is edited at the moment (cluster_pointer + sector_index).
-
 
286
                        file->ByteOfCurrSector                  = 0;                    // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
-
 
287
                        file->Mode                                              = 0;                    // mode of fileoperation (read,write)
-
 
288
                        file->Size                                              = 0;                    // the size of the opend file in bytes.
-
 
289
                        file->Position                                  = 0;                    // pointer to a character within the file 0 < fileposition < filesize
-
 
290
                        file->SectorInCache                     = 0;                    // the last sector read, wich is still in the sectorbuffer.
-
 
291
                        file->DirectorySector                   = 0;                    // the sectorposition where the directoryentry has been made.
-
 
292
                        file->DirectoryIndex                    = 0;                    // the index to the directoryentry within the specified sector.
-
 
293
                        file->Attribute                                 = 0;                    // the attribute of the file opened.
-
 
294
                        file = NULL;
-
 
295
                        return(1);
-
 
296
                }
Line -... Line 297...
-
 
297
        }
-
 
298
        return(0);
-
 
299
}
-
 
300
 
-
 
301
/****************************************************************************************************************************************/
-
 
302
/*      Function:               SeperateDirName(int8_t*, int8_t*);                                                                                                                                                                              */
-
 
303
/*                                                                                                                                                                                                                                                                              */
-
 
304
/*      Description:    This function seperates the first dirname from filepath and brings them                                                                                         */
-
 
305
/*                                      into the needed format ('test.txt' -> 'TEST    TXT')                                                                                                                            */
-
 
306
/*                                      The subpath is the pointer to the remaining substring if the filepath                                                                                           */
-
 
307
/*                                                                                                                                                                                                                                                                              */
-
 
308
/*      Returnvalue:    Return NULL on error or pointer to subpath                                                                                                                                                                                                      */
-
 
309
/****************************************************************************************************************************************/
-
 
310
int8_t* SeperateDirName(const int8_t *filepath, int8_t *dirname)
-
 
311
{
-
 
312
        int8_t* subpath = NULL;
-
 
313
        uint8_t readpointer     = 0;
-
 
314
        uint8_t writepointer = 0;
-
 
315
 
139
        if(file != NULL)                                                                                                                                // A free filepointer was found.
316
        // search subpath from beginning of filepath
140
        {
317
        subpath = NULL;
141
                file->mode      = mode;                                                                                                                 // mode of fileoperation (read,write)
318
        readpointer     = 0;
142
 
319
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
143
                if(SeekFileInDirectory(fname, file))                                                                            // if file was found
320
        while(subpath == NULL)  // search the filepath until a subpath was found.
144
                {
321
        {
145
                        if(mode == 'a')                                                                                                                 // open existing file for writing (append data at the end of the file)
-
 
146
                        {
-
 
147
                                fseek_(file, 0, SEEK_END);                                                                                      // fseek points to the end of the file
322
                if(((filepath[readpointer] == 0) || (filepath[readpointer] == '/')))    // if '/' found or end of filepath reached
148
                        }
323
                {
-
 
324
                        subpath = (int8_t*)&filepath[readpointer];                              // store the position of the first "/" found after the beginning of the filenpath
-
 
325
                }
-
 
326
                readpointer++;
-
 
327
        }
-
 
328
 
-
 
329
        // clear dirname with spaces
-
 
330
        dirname[11] = 0; // terminate dirname
-
 
331
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
-
 
332
        writepointer = 0;
149
                        else if(mode == 'r')
333
        // start seperating the dirname from the filepath.
-
 
334
        readpointer = 0;
-
 
335
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
150
                        {
336
        while( &filepath[readpointer] < subpath)
151
                                return(file);
337
        {
152
                        }
338
                if(writepointer >= 11) return(NULL);            // dirname to long
-
 
339
                if(filepath[readpointer] == '.')                        // seperating dirname and extension.
-
 
340
                {
153
                        else
341
                        if(writepointer <= 8)
154
                        {
-
 
-
 
342
                        {
155
                                fclose_(file);
343
                                readpointer++;                                          // next character in filename
156
                                file = NULL;
344
                                writepointer = 8;                                       // jump to start of extension
157
                        }
345
                        }
158
 
346
                        else return(NULL);                                              // dirbasename to long
159
                }
347
                }
160
                else
348
                else
161
                {
-
 
162
                        if((mode == 'a') || (mode == 'w'))                                                                              // specified file doesn't exist so create new file for writing data.
-
 
163
                        {
349
                {
164
                                if(CreateFileInDirectory(fname,file))                                                           // Could an entry for the new file in the rootdirectory be created?
350
                        if((0x60 < filepath[readpointer]) && (filepath[readpointer] < 0x7B))
165
                                {
351
                        {
166
                                        return(file);
352
                                dirname[writepointer] = (filepath[readpointer] - 0x20);                                 // all characters must be upper case.
167
                                }
-
 
168
                                else
-
 
169
                                {
353
                        }
-
 
354
                        else
-
 
355
                        {
170
                                        fclose_(file);
356
                                dirname[writepointer] = filepath[readpointer];
171
                                        file = NULL;
357
                        }
172
                                }
358
                        readpointer++;
173
                        }
359
                        writepointer++;
Line 174... Line -...
174
                }
-
 
175
        }
360
                }
-
 
361
        }
176
        return(file);
362
        return(subpath);
177
}
-
 
178
 
363
}
179
 
-
 
180
 
364
 
181
//________________________________________________________________________________________________________________________________________
-
 
182
// Funtion:     fflush_(File *file);
365
 
183
//
-
 
184
// Description: This function writes the data already in the buffer but not yet written to the file.
-
 
185
//
-
 
186
//________________________________________________________________________________________________________________________________________
-
 
187
 
-
 
188
s16     fflush_(File *file)
366
/**************************************************************************************************************************************+*/
189
{
-
 
-
 
367
/*      Function:       Fat16ClusterToSector( uint16_t cluster);                                                                                                                                                                                */
190
        u16 time=0;
368
/*                                                                                                                                                                                                                                                                              */
191
        u16 date=0;
369
/*      Description:    This function converts a cluster number given by the fat to the corresponding                                                                           */
192
 
-
 
193
 
-
 
194
        if(file && ((file->mode =='a') || (file->mode =='w')))
-
 
195
        {
370
/*                                      sector that points to the start of the data area that is represented by the cluster number.                                                     */
196
                if(file->byte_index > 0)                                                                                                                        // has data been added to the file?
371
/*                                                                                                                                                                                                                                                                              */
197
                {
-
 
198
                        SDC_PutSector((u32)(file->cluster_pointer + file->sector_index),file->buffer);// save the data still in the buffer
-
 
199
                }
372
/*      Returnvalue: The sector number with the data area of the given cluster                                                                                                                          */
200
                SDC_GetSector((u32)file->directory_sector,file->buffer);                                                        // read the directoryentry for this file.
373
/****************************************************************************************************************************************/
201
                DirectoryEntry = (struct DirEntry *)file->buffer;
-
 
202
                DirectoryEntry[file->directory_index].size = (u32) file->filesize;
-
 
203
                DirectoryEntry[file->directory_index].time = (u16) time;
-
 
204
                DirectoryEntry[file->directory_index].date = (u16) date;
-
 
205
                SDC_PutSector((u32)file->directory_sector,file->buffer);
-
 
206
        }
-
 
207
        return(0);
-
 
208
}
-
 
209
 
-
 
Line -... Line 374...
-
 
374
uint32_t        Fat16ClusterToSector(uint16_t cluster)
-
 
375
{
-
 
376
        if(!Partition.IsValid) return 0;
-
 
377
        if (cluster < 2) cluster = 2; // the 0. and 1. cluster in the fat are used for the media descriptor
-
 
378
        return ( (cluster - 2) * Partition.SectorsPerCluster) + Partition.FirstDataSector; // the first data sector     is represented by the 2nd cluster
-
 
379
}
-
 
380
 
-
 
381
/****************************************************************************************************************************************/
210
//________________________________________________________________________________________________________________________________________
382
/*      Function:       SectorToFat16Cluster( uint32_t sector);                                                                                                                                                                         */
211
// Funtion:     fclose_(File *file);
383
/*                                                                                                                                                                                                                                                                              */
212
//
384
/*      Description:    This function converts a given sector number given to the corresponding                                                                                         */
213
// Description: This function closes the open file by writing the remaining data from the buffer to the device and entering the filesize
-
 
214
//                              in the directory entry.
-
 
215
//________________________________________________________________________________________________________________________________________
-
 
216
 
385
/*                                      cluster number in the fat that represents this data area.                                                                                                                       */
217
void fclose_(File *file)
386
/*                                                                                                                                                                                                                                                                              */
Line 218... Line -...
218
{
-
 
219
        if(file != NULL)
-
 
220
        {
-
 
221
                fflush_(file);                                                                                                                                          // save buffered data to the disk
-
 
222
        }
-
 
223
        FreeFilePointer(file);                                                                                                                                          // and free the filepointer.
-
 
224
}
-
 
225
 
-
 
Line -... Line 387...
-
 
387
/*      Returnvalue: The cluster number representing the data area of the sector.                                                                                                                       */
-
 
388
/****************************************************************************************************************************************/
-
 
389
uint16_t        SectorToFat16Cluster(uint32_t sector)
-
 
390
{
-
 
391
        if(!Partition.IsValid) return 0;
226
//________________________________________________________________________________________________________________________________________
392
        return ((uint16_t)((sector - Partition.FirstDataSector) / Partition.SectorsPerCluster) + 2);
-
 
393
}
-
 
394
 
227
// Funtion:     u32 fread_(void *buffer, s32 size, s32 count, File *file);
395
 
228
//
396
/****************************************************************************************************************************************/
229
// Description: This function reads count objects of the specified size from the actual position of the file to the specified buffer.
-
 
230
//
397
/*      Function:       Fat16_Deinit(void);                                                                                                                                                                                                             */
231
// Returnvalue: The function returns the number of objects (not bytes) read from the file.
-
 
232
//
-
 
233
//________________________________________________________________________________________________________________________________________
398
/*                                                                                                                                                                                                                                                                              */
234
 
-
 
235
u32 fread_(void *buffer, u32 size, u32 count, File *file)
399
/*      Description:    This function uninitializes the fat 16 api                                                                                                                                                      */
236
{
400
/*                                                                                                                                                                                                                                                                              */
237
        u32 object_cnt  = 0;                                                                                                            // count the number of objects read from the file.
-
 
238
        u32 object_size         = 0;                                                                                                            // count the number of bytes read from the actual object.
401
/*      Returnvalue: The function returns "0" on success                                                                                                                                                                        */
239
        u8 *buff_pnt    = 0;                                                                                                            // a pointer to the actual bufferposition.
402
/****************************************************************************************************************************************/
240
        u8 success      = 1;                                                                                                            // no error occured during read operation to the file.
403
uint8_t Fat16_Deinit(void)
241
 
-
 
242
        buff_pnt = (u8 *) buffer;                                                                                                       // cast the void pointer to an u8 *
-
 
243
 
-
 
244
        while((object_cnt < count) && success)
-
 
245
        {
404
{
Line 246... Line -...
246
                object_size = size;
-
 
247
                while((size > 0) && success)
405
        int16_t returnvalue = 0;
248
                {
-
 
249
                        *buff_pnt = (u8) fgetchar_(file);                                                                       // read a byte from the buffer to the opened file.
-
 
250
                        buff_pnt++;
-
 
251
                        size--;
-
 
252
                }
-
 
253
                if(success) object_cnt++;
-
 
254
        }
-
 
255
 
-
 
256
        return(object_cnt);                                                                                                                                     // return the number of objects succesfully read from the file
-
 
257
}
-
 
258
 
406
        uint8_t cnt;
259
//________________________________________________________________________________________________________________________________________
-
 
260
// Funtion:     u32 fwrite_(void *buffer, s32 size, s32 count, File *file);
-
 
261
//
-
 
262
// Description: This function writes count objects of the specified size from the buffer to the actual positon within the file.
407
        // declare the filepointers as unused.
263
//
-
 
264
// Returnvalue: The function returns the number of objects (not bytes) written to the file.
-
 
265
//
-
 
266
//________________________________________________________________________________________________________________________________________
-
 
267
 
-
 
268
u32 fwrite_(void *buffer, u32 size, u32 count, File *file)
-
 
269
{
408
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
270
        u32 object_cnt  = 0;                                                                                                            // count the number of objects written to the file.
-
 
271
        u32 object_size         = 0;                                                                                                            // count the number of bytes written from the actual object.
-
 
272
        u8 *buff_pnt    = 0;                                                                                                            // a pointer to the actual bufferposition.
-
 
273
        u8 success      = 1;                                                                                                            // no error occured during write operation to the file.
-
 
274
 
-
 
275
        buff_pnt = (u8 *) buffer;                                                                                                       // cast the void pointer to an u8 *
-
 
276
 
-
 
277
        while((object_cnt < count) && success)
409
        {
Line -... Line 410...
-
 
410
                if(FilePointer[cnt].State == FSTATE_USED)
-
 
411
                {
-
 
412
                        returnvalue += fclose_(&FilePointer[cnt]); // try to close open file pointers
278
        {
413
                }
-
 
414
 
279
                object_size = size;
415
        }
-
 
416
        SDC_Deinit();                   // uninitialize interface to sd-card
-
 
417
        Partition.IsValid = 0;  // mark data in partition structure as invalid
-
 
418
        return(returnvalue);
-
 
419
}
-
 
420
 
-
 
421
/****************************************************************************************************************************************/
-
 
422
/*      Function:               Fat16_Init(void);                                                                                                                                                                                                       */
-
 
423
/*                                                                                                                                                                                                                                                                          */
-
 
424
/*      Description:    This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdir    */
-
 
425
/*                                      and stores the information in global variables.                                                                                                                                     */
Line 280... Line -...
280
                while((size > 0) && success)
-
 
281
                {
426
/*                                                                                                                                                                                                                                                                          */
282
                        success = fputchar_(file, *buff_pnt);                                                                                   // write a byte from the buffer to the opened file.
-
 
283
                        buff_pnt++;
-
 
284
                        size--;
-
 
285
                }
-
 
286
                if(success) object_cnt++;
-
 
287
        }
-
 
288
 
-
 
289
        return(object_cnt);                                                                                                                                     // return the number of objects succesfully written to the file
-
 
290
}                                                                                                                                                                                       // (!!!!! objects and not bytes !!!!)
427
/*      Returnvalue:    The function returns "0" if the filesystem is initialized.                                                                                                                      */
291
 
-
 
292
//________________________________________________________________________________________________________________________________________
-
 
Line 293... Line -...
293
// Funtion:     s16 fseek_(File *, s32, s16)
-
 
294
//
-
 
295
// Description: This function sets the pointer of the stream relative to the position
-
 
296
//                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END).
-
 
297
//
-
 
298
//________________________________________________________________________________________________________________________________________
-
 
299
 
428
/****************************************************************************************************************************************/
300
s16 fseek_(File *file, s32 offset, s16 origin)
-
 
301
{
429
uint8_t Fat16_Init(void)
302
        s32                     fposition       = 0;
-
 
303
        s16                     retvalue        = 1;
-
 
304
        u32     temp            = 0;
-
 
305
 
430
{
306
//......................................................
431
    uint8_t     cnt     = 0;
307
        if(origin == SEEK_SET)                                                                                          // Fileposition relative to the beginning of the file.
432
        uint32_t        partitionfirstsector;
-
 
433
        VBR_Entry_t *VBR;
-
 
434
        MBR_Entry_t *MBR;
Line 308... Line 435...
308
        {
435
        File_t *file;
309
                fposition = 0;
-
 
310
        }
436
        uint8_t result = 0;
311
//......................................................
437
 
312
        else if(origin == SEEK_END)                                                                                     // Fileposition relative to the end of the file.
-
 
313
        {
438
        printf("\r\n FAT16 init...");
314
                fposition  = (s32) file->filesize;
439
        Partition.IsValid = 0;
315
        }
440
 
316
//......................................................
-
 
-
 
441
        // declare the filepointers as unused.
Line 317... Line 442...
317
        else if(origin == SEEK_CUR)                                                                                     // Fileposition relative to the current position of the file.
442
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
318
        {
-
 
319
                fposition = file->fileposition;
-
 
320
        }
443
        {
321
 
444
                FilePointer[cnt].State = FSTATE_UNUSED;
322
        fposition += offset;
445
        }
-
 
446
        // set current file pinter to first position in list
-
 
447
        file = &FilePointer[0];
323
 
448
 
324
        if((fposition >= 0) && (fposition <= (s32)file->filesize))              // is the pointer still within the file?
-
 
325
        {
-
 
326
                retvalue                                = 0;
449
        // try to initialise the sd-card.
327
                file->sector_index              = 0;
450
        if(SD_SUCCESS != SDC_Init())
328
                file->byte_index                = 0;
451
        {
-
 
452
                printf("SD-Card could not be initialized.");
329
                file->fileposition              = 0;
453
                result = 1;
330
                file->cluster_pointer   = file->start_cluster;
454
                goto end;
-
 
455
        }
-
 
456
 
-
 
457
        // SD-Card is initialized successfully
331
 
458
        if(SD_SUCCESS != SDC_GetSector((uint32_t)MBR_SECTOR,file->Cache))       // Read the MasterBootRecord
332
                while(file->fileposition < fposition)
459
        {
333
                {
460
                printf("Error reading the MBR.");
-
 
461
                result = 2;
334
                        file->fileposition++;
462
                goto end;
335
                        if(file->byte_index < 511)
463
        }
-
 
464
        MBR = (MBR_Entry_t *)file->Cache;                                               // Enter the MBR using the structure MBR_Entry_t.
-
 
465
        if((MBR->PartitionEntry1.Type == PART_TYPE_FAT16_ST_32_MB) ||
-
 
466
           (MBR->PartitionEntry1.Type == PART_TYPE_FAT16_LT_32_MB) ||
336
                        {
467
           (MBR->PartitionEntry1.Type == PART_TYPE_FAT16LBA))
-
 
468
        {
-
 
469
                // get sector offset 1st partition
-
 
470
                partitionfirstsector = MBR->PartitionEntry1.NoSectorsBeforePartition;
-
 
471
                // Start of Partition is the Volume Boot Sector
-
 
472
                if(SD_SUCCESS != SDC_GetSector(partitionfirstsector,file->Cache)) // Read the volume boot record
-
 
473
                {
-
 
474
                        printf("Error reading the VBR.");
337
                                file->byte_index++;
475
                        result = 3;
-
 
476
                        goto end;
-
 
477
                }
-
 
478
        }
-
 
479
        else  // maybe the medium has no partition assuming sector 0 is the vbr
-
 
480
        {
-
 
481
                partitionfirstsector = 0;
-
 
482
        }
-
 
483
 
-
 
484
        VBR = (VBR_Entry_t *) file->Cache;                                              // Enter the VBR using the structure VBR_Entry_t.
-
 
485
        if(VBR->BytesPerSector != BYTES_PER_SECTOR)
-
 
486
        {
-
 
487
                printf("VBR: Sector size not supported.");
-
 
488
                result = 4;
-
 
489
                goto end;
-
 
490
        }
-
 
491
        Partition.SectorsPerCluster             = VBR->SectorsPerCluster;                       // Number of sectors per cluster. Depends on the memorysize of the sd-card.
338
                        }
492
        Partition.FatCopies                     = VBR->NoFATCopies;                                     // Number of fatcopies.
339
                        else
493
        Partition.MaxRootEntries                = VBR->MaxRootEntries;                          // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
340
                        {
494
        Partition.SectorsPerFat                 = VBR->SectorsPerFAT;                           // The number of sectors per FAT.
341
                                file->byte_index=0;                                                                             // reading at the beginning of new sector.
-
 
-
 
495
 
-
 
496
        /* Calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster. */
342
                                file->sector_index++;                                                                   // continue reading in next sector
497
        // Calculate the position of the FileAllocationTable:
-
 
498
        // Start + # of Reserved Sectors
-
 
499
        Partition.FirstFatSector        =   (uint32_t)(partitionfirstsector + (uint32_t)(VBR->ReservedSectors));
-
 
500
        // Calculate the position of the Rootdirectory:
-
 
501
        // Start + # of Reserved Sectors + (# of Sectors Per FAT * # of FAT Copies)
-
 
502
        Partition.FirstRootDirSector    =   Partition.FirstFatSector + (uint32_t)((uint32_t)Partition.SectorsPerFat*(uint32_t)Partition.FatCopies);
-
 
503
        // Calculate the position of the first datacluster:
-
 
504
        // Start + # of Reserved + (# of Sectors Per FAT * # of FAT Copies) + ((Maximum Root Directory Entries * 32) / Bytes per Sector)
343
                                if(file->sector_index >= SectorsPerCluster)                     // When end of cluster is reached, the next datacluster has to be searched in the FAT.
505
        Partition.FirstDataSector       =   Partition.FirstRootDirSector + (uint32_t)(Partition.MaxRootEntries>>4);  // assuming 512 Byte Per Sector
-
 
506
        // Calculate the last data sector
-
 
507
        if(VBR->NoSectors == 0)
-
 
508
        {
-
 
509
                printf("VBR: Bad number of sectors.");
-
 
510
                result = 5;
344
                                {
511
                goto end;
345
                                        if(file->fileposition < fposition)
512
        }
Line 346... Line -...
346
                                        {
-
 
347
                                                file->sector_index = 0;                                                 // start reading new cluster at first sector of the cluster.
-
 
348
                                                GetNextCluster(file);                                                   // Sets the clusterpointer of the file to the next datacluster.
-
 
349
                                        }
-
 
350
                                }
-
 
351
                        }
-
 
352
                }
-
 
Line 353... Line -...
353
                if(file->byte_index)
-
 
354
                {
-
 
355
                        temp = (u32)((u32)file->cluster_pointer + (u32)file->sector_index);
-
 
356
                        SDC_GetSector((u32)temp,file->buffer);          // FileBuffer will be written at once at the end of the cluster and has to be updated.
-
 
Line -... Line 513...
-
 
513
        Partition.LastDataSector = Partition.FirstDataSector + VBR->NoSectors - 1;
-
 
514
        // check for FAT16 in VBR of first partition
-
 
515
        if(!((VBR->FATName[0]=='F') && (VBR->FATName[1]=='A') && (VBR->FATName[2]=='T') && (VBR->FATName[3]=='1')&&(VBR->FATName[4]=='6')))
357
                }
516
        {
-
 
517
                printf("VBR: Partition ist not FAT16 type.");
-
 
518
                result = 6;
-
 
519
                goto end;
-
 
520
        }
358
        }
521
        Partition.IsValid = 1; // mark data in partition structure as valid
359
        return(retvalue);
522
        result = 0;
360
}
523
        end:
Line -... Line 524...
-
 
524
        if(result != 0) Fat16_Deinit();
-
 
525
        else printf(" ...ok");
-
 
526
        return(result);
-
 
527
}
-
 
528
 
361
 
529
 
-
 
530
 
362
//________________________________________________________________________________________________________________________________________
531
/****************************************************************************************************************************************/
363
// Funtion:     fgetchar_(File *file);
532
/* Function:    ClearCurrCluster(File_t*);                                                                                                                                                                                      */
364
//
533
/*                                                                                                                                                                                                                                                                              */
-
 
534
/* Description: This function fills the current cluster with 0.                                                                                                                                                 */
-
 
535
/*                                                                                                                                                                                                                                                                              */
-
 
536
/* Returnvalue: The function returns 1 on success else 0.                                                                                                                                                               */
365
// Description: This function reads and returns one character from the specified file.
537
/****************************************************************************************************************************************/
366
//
-
 
367
// Returnvalue: The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF.
-
 
Line -... Line 538...
-
 
538
uint8_t ClearCurrCluster(File_t * file)
-
 
539
{
-
 
540
        uint8_t retvalue = 1;
-
 
541
        uint32_t i;
-
 
542
 
-
 
543
        if((!Partition.IsValid) || (file == NULL)) return(0);
-
 
544
 
-
 
545
        for(i = 0; i < BYTES_PER_SECTOR; i++) file->Cache[i] = 0; // clear file cache
-
 
546
        for(i = 0; i < Partition.SectorsPerCluster; i++)
-
 
547
        {
-
 
548
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
-
 
549
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
-
 
550
                {
-
 
551
                        Fat16_Deinit();
-
 
552
                        retvalue = 0;
-
 
553
                }
-
 
554
        }
-
 
555
        return(retvalue);
-
 
556
}
-
 
557
 
-
 
558
/*****************************************************************************************************************************************/
-
 
559
/* Function:    GetNextCluster(File_t* );                                                                                                                                                                                        */
-
 
560
/*                                                                                                                                                                                                                                                                               */
-
 
561
/* Description: This function finds the next datacluster of the file specified with File *File.                                                                                  */
-
 
562
/*                                                                                                                                                                                                                                                                               */
-
 
563
/* Returnvalue: The function returns the next cluster or 0 if the last cluster has already reached.                                                                                                      */
-
 
564
/*****************************************************************************************************************************************/
-
 
565
uint16_t GetNextCluster(File_t * file)
368
//________________________________________________________________________________________________________________________________________
566
{
-
 
567
        uint16_t cluster = 0;
-
 
568
        uint32_t fat_byte_offset, sector, byte;
-
 
569
        Fat16Entry_t * fat;
-
 
570
 
-
 
571
        if((!Partition.IsValid) || (file == NULL)) return(cluster);
-
 
572
        // if sector is within the data area
-
 
573
        if((Partition.FirstDataSector <= file->FirstSectorOfCurrCluster)&& (file->FirstSectorOfCurrCluster <= Partition.LastDataSector))
-
 
574
        {
-
 
575
                // determine current file cluster
-
 
576
                cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);
-
 
577
                // calculate byte offset in the fat for corresponding entry
369
 
578
                fat_byte_offset = ((uint32_t)cluster)<<1; // two FAT bytes (16 bits) for every cluster
370
s16 fgetchar_(File *file)
579
                // calculate the sector that contains the current cluster within the fat
371
{
580
                sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
372
        s16 c = EOF;
-
 
373
        u32 temp1;
581
                // calculate byte offset of the current cluster within that fat sector
374
 
-
 
375
        if(file->filesize > 0)                                                                                                          // wen the end of the file is not reached, get the next character.
-
 
376
        {
-
 
377
                temp1  = (u32)file->cluster_pointer;                                            // calculate the adress of the next character to be read.
582
                byte = fat_byte_offset % BYTES_PER_SECTOR;
378
                temp1 += (u32)file->sector_index;
583
                // read this sector to the file cache
379
 
584
                if(file->SectorInCache != sector)
380
                if(file->sector_in_buffer != temp1)                                                                     // Has the content of the buffer been modified and has to be updated?
585
                {
381
                {
586
                        file->SectorInCache = sector;                                           // update sector stored in buffer
382
                        SDC_GetSector((u32)temp1,file->buffer);                                 // Read the calculated cluster.
587
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
383
                        file->sector_in_buffer = (u32)temp1;
588
                        {
384
                }
589
                                Fat16_Deinit();
Line 385... Line -...
385
                c = (s16) file->buffer[file->byte_index];
-
 
386
                file->filesize--;                                                                                                               // decrement the number of characters available.
-
 
387
 
-
 
388
                if(file->byte_index < 511)                                                                                              // continue reading from this sector until the end of the sector is reached.
-
 
389
                {
-
 
390
                        file->byte_index++;
-
 
391
                }
-
 
Line -... Line 590...
-
 
590
                                return (cluster);
-
 
591
                        }
-
 
592
                }
-
 
593
                // read the next cluster from cache
-
 
594
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
-
 
595
                cluster = fat->NextCluster;
-
 
596
                // if last cluster fat entry
392
                else                                                                                                                                    // has the end of an sector been reached->
597
                if(FAT16_CLUSTER_LAST_MIN <= cluster)
393
                {
598
                {
-
 
599
                         cluster = 0;
394
                        file->byte_index=0;                                                                                                     // continue reading at the beginning -
600
                }
-
 
601
                else
-
 
602
                {
395
                        file->sector_index++;                                                                                           // of new sector.
603
                        file->FirstSectorOfCurrCluster = Fat16ClusterToSector(cluster);
Line 396... Line -...
396
                        if(file->sector_index >= SectorsPerCluster)                                             // When the end of an cluster is reached, the next datacluster has to be searched in the FAT.
-
 
397
                        {
-
 
398
                                file->sector_index = 0;                                                                                 // start reading new cluster at first sector of the cluster.
604
                        file->SectorOfCurrCluster = 0;
399
                                GetNextCluster(file);                                                                                   // Sets the clusterpointer of the file to the next datacluster.
-
 
400
                        }
-
 
Line 401... Line -...
401
                }
-
 
402
        }
-
 
403
        return(c);
605
                        file->ByteOfCurrSector = 0;
404
}
606
                }
405
 
-
 
406
//________________________________________________________________________________________________________________________________________
-
 
407
// Funtion:     fputchar_(File *file, s8 *);
-
 
408
//
607
        }
409
// Description: This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries.
-
 
410
//
608
        return(cluster);
411
// Returnvalue: The function returns a value of 0 if the data could not be written.
609
}
412
//________________________________________________________________________________________________________________________________________
-
 
413
 
-
 
414
u8 fputchar_(File *file,s8 c)
-
 
415
{
610
 
416
        u32 ul_temp  = 0;
-
 
417
        u8 retvalue = 1;
611
 
418
 
612
/****************************************************************************************************************************************/
419
    if(file->sector_index >= SectorsPerCluster)                                                                         // if end of the cluster is reached, find next free cluster
613
/* Function:    FindNextFreeCluster(File_t *);                                                                                                                                                                          */
420
        {
-
 
421
                file->sector_index = 0;
-
 
422
                if(!AppendCluster(file)) retvalue = 0;                                                                                  // append a new and free cluster at the end of the file.
-
 
423
        }
614
/*                                                                                                                                                                                                                                                                              */
424
 
615
/* Description: This function looks in the fat to find the next free cluster                                                                                                                    */
Line 425... Line -...
425
        file->buffer[file->byte_index] = c;                                                                                             // write databyte into the buffer. The byte will be written to the device at once
-
 
426
        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.
-
 
427
        file->fileposition++;                                                                                                                           // the actual positon within the file.
-
 
428
                                                                                                                                                                                // if the buffer contains the complete sectordata.
616
/*                                                                                                                                                                                                                                                                              */
429
        if(file->byte_index < 511)                                                                                                                      // if the end of this sector is not reached yet
-
 
430
        {
-
 
Line 431... Line 617...
431
                file->byte_index++;                                                                                                                             // the next byte will be written to the next byteposition in this sector.
617
/* Returnvalue: The function returns the cluster number of the next free cluster found within the fat.                                                                  */
432
        }
618
/****************************************************************************************************************************************/
433
        else                                                                                                                                                            // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
-
 
434
        {
-
 
435
                ul_temp  = (u32)file->cluster_pointer;
619
uint16_t FindNextFreeCluster(File_t *file)
436
                ul_temp += (u32)file->sector_index;
620
{
-
 
621
        uint32_t fat_sector;                            // current sector within the fat relative to the first sector of the fat.
-
 
622
        uint32_t curr_sector;                           // current sector
-
 
623
        uint16_t fat_entry;                                     // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
-
 
624
        uint16_t free_cluster = 0;                      // next free cluster number.
437
 
625
        Fat16Entry_t * fat;
438
                SDC_PutSector((u32)ul_temp,file->buffer);
626
 
-
 
627
        if((!Partition.IsValid) || (file == NULL)) return(0);
-
 
628
 
439
                file->byte_index=0;                                                                                                                             // and the next byte will be written at the beginning of this new sector.
629
        // start searching for an empty cluster at the beginning of the fat.
-
 
630
        fat_sector = 0;
-
 
631
        do
-
 
632
        {
-
 
633
                curr_sector = Partition.FirstFatSector + fat_sector;    // calculate sector to read
440
                file->sector_index++;
634
                file->SectorInCache = curr_sector;                                              // upate the sector number of file cache.
441
                if(file->sector_index >= SectorsPerCluster)                                                                     // if end of the cluster is reached, find next free cluster
635
                if( SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))              // read sector of fat from sd-card.
Line 442... Line -...
442
                {
-
 
443
                        file->sector_index = 0;
-
 
444
                        if(!AppendCluster(file)) retvalue = 0;                                                                          // append a new and free cluster at the end of the file.
-
 
445
                }
-
 
446
        }
-
 
447
        return(retvalue);
-
 
448
}
-
 
449
 
-
 
450
//________________________________________________________________________________________________________________________________________
-
 
451
// Funtion:     fputs_(File *file, s8 *string);
-
 
452
//
-
 
453
// Description: This function writes a string to the specified file.
-
 
454
//
-
 
Line -... Line 636...
-
 
636
                {
-
 
637
                        Fat16_Deinit();
-
 
638
                        return(free_cluster);
455
//________________________________________________________________________________________________________________________________________
639
                }
456
 
-
 
-
 
640
 
457
u8 fputs_(File *file,s8 * string)
641
                fat = (Fat16Entry_t *)file->Cache;                                              // set fat pointer to file cache
-
 
642
 
458
{
643
                for(fat_entry = 0; fat_entry < FAT16_ENTRIES_PER_SECTOR; fat_entry++)                                           // look for an free cluster at all entries in this sector of the fat.
459
        u8 i=0;
644
                {
460
 
645
                        if(fat[fat_entry].NextCluster == FAT16_CLUSTER_FREE)            // empty cluster found!!
461
        while(string[i] != 0)
646
                        {
462
        {
-
 
Line 463... Line 647...
463
                fputchar_(file,string[i]);
647
                                fat[fat_entry].NextCluster = FAT16_CLUSTER_LAST_MAX;    // mark this fat-entry as used
464
                i++;
648
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // and save the sector at the sd-card.
465
        }
649
                                {
-
 
650
                                        Fat16_Deinit();
466
        return(0);
651
                                        return(free_cluster);
467
}
652
                                }
-
 
653
                                free_cluster = (uint16_t)(fat_sector * FAT16_ENTRIES_PER_SECTOR + (uint32_t)fat_entry);
-
 
654
                                fat_entry = FAT16_ENTRIES_PER_SECTOR;                                   // terminate the search for a free cluster in this sector.
468
 
655
                        }
-
 
656
                }
-
 
657
                fat_sector++;                                                                                                   // continue the search in next fat sector
-
 
658
        // repeat until the end of the fat is  reached and no free cluster has been found so far
469
//________________________________________________________________________________________________________________________________________
659
        }while((fat_sector < Partition.SectorsPerFat) && (!free_cluster));
470
// Funtion:     s8 * fgets_(s8 *string, s16 count, File *file)
-
 
471
//
-
 
472
// Description: This function reads a string from the file to the specifies string.
-
 
473
//
-
 
474
// Returnvalue: A pointer to the string written from the file.
-
 
475
//________________________________________________________________________________________________________________________________________
-
 
476
 
-
 
477
s8 * fgets_(s8 *string, s16 count, File *file)
-
 
478
{
660
        return(free_cluster);
Line 479... Line -...
479
        s16 buff_pnt = 0;
-
 
480
        s16 buff_tmp = 0;
-
 
481
        u8 state = 0;                                                                                                                   // Variable used for a statemachine to recognize the end of a line.
-
 
482
 
-
 
483
        while(count > 1)                                                                                                                                        // read the count-1 characters from the file to the string.
-
 
484
        {
-
 
485
                buff_tmp = fgetchar_(file);                                                                                                             // read a character from the opened file.
-
 
486
                switch(state)
661
}
487
                {
-
 
Line 488... Line 662...
488
                        case 0:
662
 
489
                                if(buff_tmp == 0x0D) state++;
663
 
-
 
664
/****************************************************************************************************************************************************/
-
 
665
/* Function:    int16_t fseek_(File_t *, int32_t *, uint8_t)                                                                                                                                                                                                            */
490
                        break;
666
/*                                                                                                                                                                                                                                                                                                      */
491
 
-
 
492
                        case 1:
667
/* Description: This function sets the pointer of the stream relative to the position                                                                                                                           */
-
 
668
/*                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END)                                                                                                                                                                      */
Line 493... Line 669...
493
                                if(buff_tmp == 0x0A)
669
/* Returnvalue: Is 1 if seek was successful                                                                                                                                                                                                                                                                     */
494
                                {
670
/****************************************************************************************************************************************************/
-
 
671
int16_t fseek_(File_t *file, int32_t offset, int16_t origin)
-
 
672
{
495
                                        count = 1;
673
        int32_t         fposition       = 0;
496
                                }
674
        int16_t         retvalue        = 1;
497
                                state = 0;
675
 
498
                        break;
676
        if((!Partition.IsValid) || (file == NULL)) return(0);
499
                }
-
 
500
                if(buff_tmp == EOF) {buff_tmp = 0; count = 1;}                                                                  // is the end of the file reached, terminate the string with zero.
-
 
-
 
677
        switch(origin)
501
                string[buff_pnt] = (s8) buff_tmp;
678
        {
502
                count--;
679
                case SEEK_SET:                          // Fileposition relative to the beginning of the file.
503
                buff_pnt++;
-
 
504
        }
-
 
505
        string[buff_pnt] = 0;
-
 
506
        return(string);
680
                        fposition = 0;
507
}
681
                        break;
508
 
682
                case SEEK_END:                          // Fileposition relative to the end of the file.
509
//________________________________________________________________________________________________________________________________________
-
 
510
// Funtion:     u8 fexist_(u8*, File *file);
-
 
511
//
-
 
512
// Description: This function searches the specified file and returns 0 if the file was not found.
-
 
513
//
-
 
514
//
-
 
515
//      Return:         0 = file does not exist
-
 
516
//                              1 = file exists
683
                        fposition = (int32_t)file->Size;
517
//________________________________________________________________________________________________________________________________________
-
 
518
 
-
 
519
u8 fexist_(s8 *fname)
-
 
520
{
-
 
521
        File *file;
-
 
522
 
-
 
523
        file = ReserveFilePointer();
-
 
524
 
-
 
525
        if(file != NULL)
-
 
526
        {
-
 
527
                if((file = fopen_(fname,'r'))!= NULL)
-
 
528
                {
-
 
529
                        fclose_(file);
-
 
530
                        return(1);
-
 
531
                }
-
 
532
                else
-
 
533
                {
-
 
534
                        return(0);
-
 
535
                }
-
 
536
        }
-
 
537
        else
-
 
538
        {
-
 
539
                return(0);
-
 
540
        }
-
 
541
}
-
 
542
 
-
 
543
//________________________________________________________________________________________________________________________________________
-
 
544
// Funtion:     GetNextCluster(File *file);
-
 
545
//
-
 
546
// Description: This function finds the next datacluster of the file specified with File *file.
-
 
547
//
-
 
548
// Returnvalue: The function returns "0" if the last cluster has already been reached.
-
 
549
//________________________________________________________________________________________________________________________________________
-
 
550
 
-
 
551
u16 GetNextCluster(File *file)
684
                        break;
552
{
685
                case SEEK_CUR:                          // Fileposition relative to the current position of the file.
553
        u32 fat_pointer                 =       0;
686
                default:
554
        u32 fat_sector_offset   =       0;
-
 
555
        u32 ul_tmp                              =       0;
-
 
556
        u8 retvalue                             =       0;                                                                              // no new cluster found yet.
-
 
557
 
687
                        fposition = file->Position;
558
 
-
 
559
        if((file->cluster_pointer >= RootDirectory) && (file->cluster_pointer < (RootDirectory + 31)))
-
 
560
        {                                                                                                                                                               // Is the next cluster searched within the rootdirectory and available?
-
 
561
                file->cluster_pointer++;                                                                                                        // the rootdirectory is a linear adress space of 32 clusters.
-
 
562
                retvalue = 1;                                                                                                                           // and the next cluster has been found.
-
 
563
        }
-
 
564
        else if(file->cluster_pointer > (RootDirectory + 31))                                                   // The specified cluster is within the FAT.
-
 
565
        {
-
 
566
                fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));           // Calculate index of actual cluster within the FAT.
-
 
567
                fat_sector_offset  /= SectorsPerCluster;                                                                        // calculate the index of the actual sector within the FAT.
-
 
568
                fat_sector_offset  += 2;                                                                                                        // In Fat16 clusterpositions have an offset of two.
-
 
569
                fat_pointer = (fat_sector_offset%0x100);                                                                        // Calculate the sector within the cluster.
-
 
570
                fat_sector_offset   = (fat_sector_offset>>8);                                                           // and the position within the sector.
-
 
571
 
-
 
572
                SDC_GetSector((u32)(FileAllocationTable + fat_sector_offset),file->buffer);
-
 
573
                file->sector_in_buffer = (FileAllocationTable + fat_sector_offset);                     // Mark that new sector has been read.
-
 
574
 
-
 
575
                ul_tmp  = (u32)file->buffer[((fat_pointer << 1)+1)];                            // Read next sector information from calculated clusterposition.
-
 
576
                ul_tmp  = (ul_tmp << 8);
-
 
577
                ul_tmp |= (u32)file->buffer[(fat_pointer << 1)];
-
 
578
                ul_tmp -=2;                                                                                                                                     // next datacluster is clusterposition in fat - 2.
-
 
579
                ul_tmp *= SectorsPerCluster;                                                                                            // calculate sectorposition of new cluster
-
 
580
                ul_tmp += FirstDataCluster;                                                                                                     // in relation to first datacluster of the disk.
-
 
581
 
-
 
582
                if(ul_tmp < 0xfff7)                                                                                                                     // has a new cluster been read or was the end of the fat reached?
-
 
583
                {
-
 
584
                        file->cluster_pointer = (u32) ul_tmp;                                           // continue reading the file at the beginning of new datacluster.
-
 
585
                        retvalue = 1;                                                                                                                   // a new cluster was found.
-
 
586
                }
-
 
587
        }
-
 
588
        return(retvalue);
-
 
589
}
-
 
590
 
-
 
591
//________________________________________________________________________________________________________________________________________
-
 
592
// Funtion:     u16 FindNextFreeCluster(void)
688
                        break;
593
//
689
        }
594
// Description: This function looks in the FAT to find the next free datacluster
-
 
595
//
690
 
596
// Returnvalue: The function returns the adress of the next free cluster found within the fAT.
-
 
597
//________________________________________________________________________________________________________________________________________
691
        fposition += offset;
598
 
-
 
599
u16 FindNextFreeCluster(File *file)
-
 
600
{
692
 
601
        u32 fat_pointer                 =       0;                                                      // Pointer to the first sector of the FAT.
-
 
602
        u32 ul_tmp                              =       0;                                                      // temporary variable used to calculate a sectornumber.
-
 
603
        u16  fat_sector_offset  =       0;                                                      // index to a sector within the FAT.
-
 
604
        u16  fat_entry                  =       0;                                                      // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
-
 
605
        u16  free_cluster                       =       0;                                                      // a pointer to the first sector of the next free cluster.
-
 
606
 
-
 
607
        fat_pointer = (u32) FileAllocationTable;                                        // start searching for empty cluster at the beginning of the fat.
-
 
608
                                                                                                                                                // if the end of the fat is not reached yet and no free cluster has been found
-
 
609
        while((fat_sector_offset < SectorsPerFat) && (!free_cluster))
-
 
610
        {
-
 
611
                ul_tmp = (u32) ((u32)fat_pointer + (u32)fat_sector_offset);
693
        if((fposition >= 0) && (fposition <= (int32_t)file->Size))              // is the pointer still within the file?
612
                SDC_GetSector((u32)ul_tmp,file->buffer);                                // read next sector of FAT.
-
 
613
                file->sector_in_buffer = ul_tmp;                                                                // remember the number of the sector in FileBuffer.
-
 
614
                Fat = (struct FatEntry *)file->buffer;
-
 
615
                for(fat_entry=0;fat_entry<256;fat_entry++)                                              // look for an free cluster at all entries in this sector of the fat.
-
 
616
                {
-
 
617
                        if(Fat[fat_entry].next_cluster == 0x0000)                                       // empty cluster found!!
-
 
618
                        {
-
 
619
                                Fat[fat_entry].next_cluster = 0xffff;                                   // mark this fat-entry as used and save it to the device.
-
 
620
                                SDC_PutSector((u32)file->sector_in_buffer,file->buffer);
-
 
621
                                free_cluster  = fat_entry;                                                              // the relative position of the free cluster found in this sector of the FAT.
-
 
622
                                free_cluster += (fat_sector_offset << 8);                               // calculate the absolute position of the free cluster in the FAT;
-
 
623
                                fat_entry = 256;                                                                                // terminate the search for a free cluster in this sector.
-
 
624
                        }
-
 
625
                }
-
 
626
                fat_sector_offset++;
-
 
627
        }
-
 
628
return(free_cluster);
-
 
629
}
-
 
630
 
694
        {
Line 631... Line 695...
631
//________________________________________________________________________________________________________________________________________
695
                // reset file position to start of the file
632
// Funtion:     u16 AppendCluster(File *file);
696
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
633
//
-
 
-
 
697
                file->SectorOfCurrCluster       = 0;
634
// Description: This function finds the next free datacluster on the disk and appends it to the specified file.
698
                file->ByteOfCurrSector          = 0;
635
//
-
 
636
// Returnvalue: This funktion returns 1 if a cluster was appended to the specified file.
699
                file->Position                          = 0;
637
//________________________________________________________________________________________________________________________________________
700
 
638
 
-
 
639
u8 AppendCluster(File *file)
701
                while(file->Position < fposition)       // repeat until the current position is less than target
640
{
702
                {
641
        u16  free_cluster = 0;
703
                        file->Position++;                               // increment file position
642
        u32 fat_pointer = 0;
704
                        file->ByteOfCurrSector++;               // next byte in current sector
-
 
705
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
-
 
706
                        {
643
        u8 retvalue     = 0;
707
                                file->ByteOfCurrSector = 0;                                                                             // reading at the beginning of new sector.
644
 
708
                                file->SectorOfCurrCluster++;                                                                    // continue reading in next sector
-
 
709
                                if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster)    // if end of cluster is reached, the next datacluster has to be searched in the FAT.
645
        free_cluster = FindNextFreeCluster(file);                                                                                               // the next free cluster found on the disk.
710
                                {
646
        if(free_cluster) retvalue = 1;                                                                                                                  // A free cluster was found and can be added to the end of the file.
711
                                        if(GetNextCluster(file))                                                                        // Sets the clusterpointer of the file to the next datacluster.
-
 
712
                                        {
-
 
713
                                                file->SectorOfCurrCluster = 0;
647
        fat_pointer  = FileAllocationTable;                                                                                                             // Set Pointer to the beginnig of the FAT.
714
                                        }
648
        fat_pointer += (u32)((u32)GetFatClusterOffset(file) >> 8);                                                              // find the sector in the FAT with 256 entries per sector.
715
                                        else // the last cluster was allready reached
649
 
716
                                        {
650
    SDC_GetSector(fat_pointer,file->buffer);
-
 
651
        Fat = (struct FatEntry *)file->buffer;
-
 
-
 
717
                                                file->SectorOfCurrCluster--;                                                    // jump back to the ast sector in the last cluster
-
 
718
                                                file->ByteOfCurrSector = BYTES_PER_SECTOR;                              // set ByteOfCurrSector one byte over sector end
652
        Fat[GetFatSectorIndex(file)].next_cluster = free_cluster;                                                               // append the free cluster to the end of the file in the FAT.
719
                                        }
653
        SDC_PutSector((u32)fat_pointer,file->buffer);                                                                                   // save the modified sector to the FAT.
720
                                }
654
 
721
                        }
655
        fat_pointer  = (u32)free_cluster;
722
                }
-
 
723
        }
656
        fat_pointer -= 2;
724
        if(file->Position == fposition) retvalue = 0;
-
 
725
        return(retvalue);
-
 
726
}
-
 
727
 
-
 
728
 
-
 
729
/****************************************************************************************************************************************/
-
 
730
/* Function:    uint16_t DeleteClusterChain(File *file);                                                                                                                                                                                */
-
 
731
/*                                                                                                                                                                                                                                                                              */
-
 
732
/* Description: This function trances along a cluster chain in the fat and frees all clusters visited.                                                                  */
-
 
733
/*                                                                                                                                                                                                                                                                              */
-
 
734
/****************************************************************************************************************************************/
-
 
735
uint8_t DeleteClusterChain(uint16_t StartCluster)
-
 
736
{
-
 
737
        uint16_t cluster;
-
 
738
        uint32_t fat_byte_offset, sector, byte;
-
 
739
        Fat16Entry_t * fat;
-
 
740
        uint8_t buffer[BYTES_PER_SECTOR];
-
 
741
        uint32_t sector_in_buffer = 0;
657
        fat_pointer *= SectorsPerCluster;
742
        uint8_t repeat = 0;
-
 
743
 
-
 
744
        if(!Partition.IsValid) return 0;
-
 
745
 
-
 
746
        cluster = StartCluster; // init chain trace
-
 
747
        // calculate byte offset in the fat for corresponding entry
-
 
748
        fat_byte_offset = ((uint32_t)cluster)<<1; // two FAT bytes (16 bits) for every cluster
658
        fat_pointer += FirstDataCluster;
749
        // calculate the sector that contains the current cluster within the fat
659
 
-
 
Line 660... Line -...
660
        file->cluster_pointer = fat_pointer;                                                                                                    // continue wrtiting to the file in the new and free datacluster.
-
 
661
        return(retvalue);                                                                                                                                               // return 1 when a new cluster was appended to the file
-
 
Line -... Line 750...
-
 
750
        sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
751
        // calculate byte offset of the current cluster within that fat sector
-
 
752
        byte = fat_byte_offset % BYTES_PER_SECTOR;
-
 
753
        do
-
 
754
        {
-
 
755
                if(sector != sector_in_buffer)
-
 
756
                {
-
 
757
                        // read this sector to buffer
-
 
758
                        sector_in_buffer = sector;
-
 
759
                        if(SD_SUCCESS != SDC_GetSector(sector_in_buffer, buffer)) return 0;     // read sector from sd-card
-
 
760
                }
-
 
761
                // read the next cluster from cache
-
 
762
                fat = (Fat16Entry_t *)(&(buffer[byte]));
-
 
763
                cluster = fat->NextCluster;
-
 
764
                if((FAT16_CLUSTER_USED_MIN <= cluster) && (cluster <= FAT16_CLUSTER_USED_MAX) ) repeat = 1;
662
}
765
                else repeat = 0;
-
 
766
 
-
 
767
                fat->NextCluster =      FAT16_CLUSTER_FREE; // mark current cluster as free
663
 
768
                // calculate byte offset in the fat for corresponding entry
-
 
769
                fat_byte_offset = ((uint32_t)cluster)<<1; // two FAT bytes (16 bits) for every cluster
-
 
770
                // calculate the sector that contains the current cluster within the fat
664
 
771
                sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
772
                // calculate byte offset of the current cluster within that fat sector
-
 
773
                byte = fat_byte_offset % BYTES_PER_SECTOR;
665
//________________________________________________________________________________________________________________________________________
774
                // if new sector is not the sector in buffer or the last cluster in the chain was traced
666
// Funtion:     void DeleteClusterChain(u16 startcluster);
775
                if((sector != sector_in_buffer) || !repeat)
667
//
776
                {       // write sector in buffer
-
 
777
                        if(SD_SUCCESS != SDC_PutSector(sector_in_buffer,buffer)) return 0;
668
// Description: This function frees all the clusters used for file from the fat.
778
                }
-
 
779
        }
-
 
780
        while(repeat);
669
//
781
 
670
// Returnvalue: none
-
 
671
//________________________________________________________________________________________________________________________________________
782
        return 1;
672
 
-
 
673
void DeleteClusterChain(u16 startcluster)
-
 
674
{
-
 
675
        u16 fat_index                   =       0;
783
}
676
        u16 fat_sector_offset   =       0;
-
 
677
        u32 sector_in_buffer    =       0;
784
 
678
        u32 ul_temp                             =       0;
-
 
679
        u8 buffer[512];
785
 
680
 
-
 
681
        fat_index = (startcluster % 0x100);                                                                                             // Calculate the sector within the cluster.
-
 
682
        fat_sector_offset = (startcluster >> 8);                                                                                        // and the position within the sector.
786
/****************************************************************************************************************************************/
683
        ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
787
/* Function:    uint16_t AppendCluster(File *file);                                                                                                                                                                                     */
-
 
788
/*                                                                                                                                                                                                                                                                              */
684
 
789
/* Description: This function looks in the fat to find the next free cluster and appends it to the file.                                                                */
685
 
790
/*                                                                                                                                                                                                                                                                              */
686
        do
791
/* Returnvalue: The function returns the appened cluster number or 0 of no cluster was appended.                                                                                                                                                */
687
        {
792
/****************************************************************************************************************************************/
688
                if(sector_in_buffer != ul_temp)
793
uint16_t AppendCluster(File_t *file)
689
                {
794
{
690
                        sector_in_buffer = ul_temp;
795
        uint16_t last_cluster, new_cluster = 0;
Line 691... Line 796...
691
                        SDC_GetSector(ul_temp,buffer);
796
        uint32_t fat_byte_offset, sector, byte;
-
 
797
        Fat16Entry_t * fat;
692
                }
798
 
693
                Fat = (struct FatEntry *)buffer;
-
 
694
 
799
        if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
695
                startcluster = Fat[fat_index].next_cluster;
-
 
-
 
800
 
-
 
801
        new_cluster = FindNextFreeCluster(file);        // the next free cluster found on the disk.
696
                Fat[fat_index].next_cluster = 0x0000;                                                                                   // free the cluster within the fat.
802
        if(new_cluster)
697
 
-
 
698
                fat_index = (startcluster % 0x100);                                                                                             // Calculate the sector within the cluster.
803
        {       // A free cluster was found and can be added to the end of the file.
699
                fat_sector_offset = (startcluster >> 8);                                                                                        // and the position within the sector.
804
                fseek_(file, 0, SEEK_END);                                                                                                      // jump to the end of the file
-
 
805
                last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);            // determine current file cluster
700
                ul_temp = (u32)(FileAllocationTable + fat_sector_offset);
806
                fat_byte_offset = ((uint32_t)last_cluster)<<1;
Line 701... Line 807...
701
                if((sector_in_buffer != ul_temp) || (startcluster == 0xffff))
807
                sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
808
                byte = fat_byte_offset % BYTES_PER_SECTOR;
702
                {
809
 
-
 
810
                if(file->SectorInCache != sector)
Line 703... Line 811...
703
                        SDC_PutSector(sector_in_buffer,buffer);
811
                {
704
                }
-
 
-
 
812
                        file->SectorInCache = sector;                                           // update sector stored in buffer
Line 705... Line -...
705
        }
-
 
706
        while(startcluster != 0xffff);                                                                                                                  // last cluster has been deleted.
813
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
707
}
-
 
708
 
814
                        {
709
 
815
                                Fat16_Deinit();
710
//________________________________________________________________________________________________________________________________________
-
 
711
// Funtion:     u16 GetFatClusterIndex(File *file);
-
 
712
//
-
 
713
// Description: This function returns the clusterindex of the cluster specified by file->cluster_pointer of the specified file.
-
 
714
//
-
 
715
//________________________________________________________________________________________________________________________________________
-
 
716
 
-
 
Line -... Line 816...
-
 
816
                                return(0);
-
 
817
                        }
717
u16 GetFatClusterOffset(File *file)
818
                }
718
{
819
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
719
        u32 fat_sector_offset   =       0;
-
 
720
 
820
                fat->NextCluster = new_cluster;                                                 // append the free cluster to the end of the file in the FAT.
721
        fat_sector_offset   = ((file->cluster_pointer) - (FirstDataCluster));                           // Calculate index of actual cluster in FAT.
-
 
722
        fat_sector_offset  /= SectorsPerCluster;
821
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // save the modified sector to the FAT.
723
        fat_sector_offset  += 2;                                                                                                                        // In Fat16 clusterpositions have an offset of two.
-
 
724
 
-
 
725
        return((u16)fat_sector_offset);
-
 
726
}
-
 
727
 
-
 
728
//________________________________________________________________________________________________________________________________________
-
 
729
// Funtion:     u16 GetFatSectorIndex(File *file);
822
                {
730
//
823
                        Fat16_Deinit();
731
// Description: This function returns the sectorindex of the cluster specified by file->cluster_pointer of the specified file.
-
 
732
//
824
                        return(0);
733
//________________________________________________________________________________________________________________________________________
825
                }
734
 
-
 
735
u16 GetFatSectorIndex(File *file)
-
 
736
{
-
 
737
        u16 fat_pointer                 =       0;
-
 
738
 
-
 
739
        fat_pointer = GetFatClusterOffset(file);
-
 
740
        fat_pointer = fat_pointer % 0x100;                                                                                                      // Calculate the clusterposition in the fat
-
 
741
 
-
 
742
        return(fat_pointer);
826
                file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster);
743
}
-
 
744
 
-
 
745
//________________________________________________________________________________________________________________________________________
-
 
746
// Funtion:     u16 CreateFileInDirectory(u8 *, File *)
-
 
747
//
-
 
748
// Description: This function looks for the next free position in the directory and creates an entry. The type of an directoryentry is
-
 
749
//                              specified by the attribute.
-
 
750
//                              bit0:   unused
-
 
751
//                              bit1:   archive
-
 
752
//                              bit2:   read_only
-
 
753
//                              bit3:   system
-
 
754
//                              bit4:   directory
-
 
755
//                              bit5:   volume
-
 
756
//________________________________________________________________________________________________________________________________________
-
 
757
 
-
 
758
u8 CreateFileInDirectory(s8 *fname, File *file)
827
                file->SectorOfCurrCluster = 0;
-
 
828
                file->ByteOfCurrSector = 0;
-
 
829
        }
759
{
830
        return(new_cluster);
760
        u16     rootentry       = 0;                                                                                                    // index to an entry in the rootdirectory.
831
}
761
        u16     cnt_enries_searched = 0;                                                                                        // count the number of rootentries which have been searched already.
832
 
762
        u8              i = 0;
833
/****************************************************************************************************************************************************/
-
 
834
/* Function:    DirectoryEntryExist(int8_t *, uint8_t, uint8_t, File_t *)                                                                                                                                                                                       */
-
 
835
/*                                                                                                                                                                                                                                                                                                      */
763
        u16     sector_offset = 0;                                                                                                      // index to the sector of the Rootentry which is searched momentarily
836
/* Description: This function searches all possible dir entries until the file or directory is found or the end of the directory is reached                     */
-
 
837
/*                                                                                                                                                                                                                                                                                                      */
-
 
838
/* Returnvalue: This function returns 1 if the directory entry specified was found.                                                                                                                                     */
-
 
839
/****************************************************************************************************************************************************/
-
 
840
uint8_t DirectoryEntryExist(int8_t *dirname, uint8_t attribfilter, uint8_t attribmask, File_t *file)
764
        u8              retvalue = 0;
841
{
765
        u32             cluster_temp = 0;
842
        uint32_t        dir_sector, max_dir_sector, curr_sector;
766
        u16             cluster = 0;
843
        uint16_t        dir_entry = 0;
-
 
844
 
-
 
845
        uint16_t        end_of_directory_not_reached = 0;
-
 
846
        uint8_t         i = 0;
-
 
847
        uint8_t         direntry_exist = 0;
-
 
848
        DirEntry_t * dir;
-
 
849
 
-
 
850
        // if incomming pointers are useless return immediatly
-
 
851
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
-
 
852
 
-
 
853
        // dir entries can be searched only in filesclusters that have
-
 
854
        // a corresponding dir entry with adir-flag set in its attribute
-
 
855
        // or direct within the root directory area
-
 
856
 
767
        s8 name[11]     = "           ";
857
        file->FirstSectorOfFirstCluster = 0;
768
 
-
 
769
        SeperateFileName(fname,name);
858
        // no current directory exist therefore assume searching in the root
770
 
859
        if(file->DirectorySector == 0)
771
        cluster_temp = (u32)FindNextFreeCluster(file);                                                          // the next free cluster on the disk.
860
        {
772
 
861
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
Line 773... Line -...
773
        if(cluster_temp)                                                                                                                        // if a free cluster is available:
-
 
774
        {
-
 
775
                cluster = (u16)cluster_temp;                                                                                    // remember the index of the free datacluster found for the directory entry.
-
 
776
                cluster_temp -=2;                                                                                                               // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
-
 
777
                cluster_temp *= SectorsPerCluster;                                                                              // Calculate relative sectorindex of first datacluster.
-
 
778
                file->start_cluster   = (FirstDataCluster + cluster_temp);                              // Calculate absolute sectorposition of first datacluster.
862
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
779
                file->cluster_pointer = file->start_cluster;                                                    // start reading the file with the first sector of the first datacluster.
-
 
780
 
-
 
781
                                                                                                                                                                // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
863
        }
782
                do
-
 
783
                {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
-
 
784
                        rootentry=0;
-
 
785
                        SDC_GetSector((u32)(CWD + sector_offset),file->buffer); // Read the Rootdirectory.
-
 
786
                        DirectoryEntry = (struct DirEntry *)file->buffer;
-
 
787
                        while((rootentry<16) && (!retvalue))
864
        // within the root directory area we can read sectors sequentially until the end of this area
788
                        {
-
 
789
                                if((DirectoryEntry[rootentry].attribute == 0) || (DirectoryEntry[rootentry].attribute == 0xE5)) // empty directory entry found
-
 
790
                                {
865
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
791
                                        for(i=0;i<11;i++) DirectoryEntry[rootentry].name[i] = name[i];          // Kopie the filename and the file extension to the directoryentry.
-
 
792
                                        DirectoryEntry[rootentry].attribute    = _FILE;                                         // Set the fileattribute to archive to reserve the directoryentry.
-
 
793
                                        DirectoryEntry[rootentry].startcluster = cluster;                                               // copy the location of the first datacluster to the directoryentry.
-
 
794
                                        DirectoryEntry[rootentry].size     = 0;                                                                 // the new createted file has no content yet.
-
 
795
                                        file->directory_sector = (u32) (CWD + sector_offset);
-
 
796
                                        file->directory_index  = (u8) rootentry;
-
 
797
                                        retvalue = 1;
-
 
798
                                        SDC_PutSector((u32)(CWD + sector_offset),file->buffer);
-
 
799
                                }
-
 
Line 800... Line 866...
800
                                rootentry++;
866
        {
801
                                cnt_enries_searched++;
867
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
802
                        }
868
        }
803
                        if(!retvalue)                                                                                                                                   // file not found in this sector so take next sector.
869
        // within the data clusters we can read sectors sequentially only within the cluster
804
                        {
870
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
805
                                rootentry = 0;
871
        {
-
 
872
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
-
 
873
        }
806
                                sector_offset++;
874
        else return (direntry_exist); // bad sector range for directory sector of the file
807
                        }
875
        // if search area is not defined yet
808
                }
876
        if(file->FirstSectorOfFirstCluster == 0)
809
                while((cnt_enries_searched< PossibleRootEntries) && (!retvalue));
877
        {
810
 
-
 
811
        }
878
                // check if the directory entry of current file is existent and has the dir-flag set
-
 
879
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
-
 
880
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
881
                {
-
 
882
                        Fat16_Deinit();
812
        return(retvalue);                                                                                                                                       // return 1 if file has been created otherwise return 0.
883
                        return(direntry_exist);
-
 
884
                }
-
 
885
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
886
                switch((uint8_t)dir[file->DirectoryIndex].Name[0])                                      // check if current directory exist
-
 
887
                {
-
 
888
                        case SLOT_EMPTY:
-
 
889
                        case SLOT_DELETED:
-
 
890
                                // the directrory pointer of this file points to a deleted or not existen directory
-
 
891
                                // therefore no file or subdirectory can be created
-
 
892
                                return (direntry_exist);
813
}
893
                                break;
-
 
894
                        default:        // and is a real directory
-
 
895
                                if((dir[file->DirectoryIndex].Attribute & ATTR_SUBDIRECTORY) != ATTR_SUBDIRECTORY)
-
 
896
                                {       // current file is not a directory therefore no file or subdirectory can be created here
814
 
897
                                        return (direntry_exist);
815
//________________________________________________________________________________________________________________________________________
898
                                }
816
// Funtion:     u16 SeekFileInDirectory(s8 *fname, File *)
899
                                break;
-
 
900
                }
817
//
901
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dir[file->DirectoryIndex].StartCluster);
818
// Description: this function searches all possible entries withint the actual directory for the specified object.
902
        }
819
//
903
 
820
// Returnvalue: This function returns 1 if the directoryentry specified was found.
904
        // update current file data area position to start of first cluster
-
 
905
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
-
 
906
        file->SectorOfCurrCluster               = 0;
-
 
907
        file->ByteOfCurrSector                  = 0;
-
 
908
 
-
 
909
        do // loop over all data clusters of the current directory entry
-
 
910
        {
-
 
911
                dir_sector = 0; // reset sector counter within a new cluster
-
 
912
                do // loop over all sectors of a cluster or all sectors of the root directory
-
 
913
                {
-
 
914
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
-
 
915
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
-
 
916
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
-
 
917
                        {
-
 
918
                                Fat16_Deinit();
-
 
919
                                return(direntry_exist);
-
 
920
                        }
-
 
921
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
922
                        // search all directory entries within that sector
-
 
923
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
-
 
924
                        {   // check for existing dir entry
-
 
925
                                switch((uint8_t)dir[dir_entry].Name[0])
-
 
926
                                {
-
 
927
                                        case SLOT_EMPTY:
-
 
928
                                        case SLOT_DELETED:
-
 
929
                                                // ignore empty or deleted dir entries
-
 
930
                                                break;
-
 
931
                                        default:
-
 
932
                                                // if existing check attributes before names are compared will safe performance
-
 
933
                                                if ((dir[dir_entry].Attribute & attribmask) != attribfilter) break; // attribute must match
-
 
934
                                                // then compare the name to the giveb dirname (first 11 characters include 8 chars of basename and 3 chars extension.)
-
 
935
                                                i = 0;
-
 
936
                                                while((i < 11) && (dir[dir_entry].Name[i] == dirname[i])) i++;
821
//________________________________________________________________________________________________________________________________________
937
                                                if (i < 10) break; // names does not match
-
 
938
                                                // if dirname and attribute have matched
-
 
939
                                                file->Attribute = dir[dir_entry].Attribute; // store attribute of found dir entry
-
 
940
                                                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dir[dir_entry].StartCluster); // set sector of first data cluster
-
 
941
                                                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
-
 
942
                                                file->SectorOfCurrCluster = 0;
-
 
943
                                                file->ByteOfCurrSector = 0;
-
 
944
                                                file->DirectorySector = curr_sector; // current sector
-
 
945
                                                file->DirectoryIndex  = dir_entry; // current direntry in current sector
-
 
946
                                                file->Size = dir[dir_entry].Size;
-
 
947
                                                direntry_exist = 1; // mark as found
-
 
948
                                                dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
-
 
949
                                } // end of first byte of name check
-
 
950
                        }
-
 
951
                        dir_sector++; // search next sector
-
 
952
                // stop if we reached the end of the cluster or the end of the root dir
-
 
953
                }while((dir_sector < max_dir_sector) && (!direntry_exist));
-
 
954
 
-
 
955
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
-
 
956
                if(!direntry_exist && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
-
 
957
                {
-
 
958
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
-
 
959
                }
-
 
960
        }while((end_of_directory_not_reached) && (!direntry_exist)); // repeat until a next cluster exist an no
-
 
961
        return(direntry_exist);
-
 
962
}
-
 
963
 
-
 
964
 
-
 
965
/****************************************************************************************************************************************/
-
 
966
/*      Function:               CreateDirectoryEntry(int8_t *, uint16_t, File_t *)                                                                                                                                                      */
-
 
967
/*                                                                                                                                                                                                                                                                              */
-
 
968
/*      Description:    This function looks for the next free position in the directory and creates an entry.                                                           */
-
 
969
/*                                      The type of an directory entry is specified by the file attribute.                                                                                                      */
-
 
970
/*                                                                                                                                                                                                                                                                              */
822
 
971
/*      Returnvalue:    Return 0 on error                                                                                                                                                                                                       */
-
 
972
/****************************************************************************************************************************************/
823
u8 SeekFileInDirectory(s8 *fname, File *file)
973
uint8_t CreateDirectoryEntry(int8_t *dirname, uint8_t attrib, File_t *file)
824
{
974
{
825
        u16     rootentry=0;
975
        uint32_t        dir_sector, max_dir_sector, curr_sector;
-
 
976
        uint16_t        dir_entry       = 0;
826
        u16     end_of_directory_not_reached = 0;                                                                       // the directory has been read completely without a result.
977
        uint16_t        subdircluster, dircluster = 0;
-
 
978
        uint16_t        end_of_directory_not_reached = 0;
-
 
979
        uint8_t         i                       = 0;
-
 
980
        uint8_t         retvalue        = 0;
-
 
981
        DirEntry_t*     dir;
827
        u8              i=0;
982
 
-
 
983
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return (retvalue);
-
 
984
        // It is not checked here that the dir entry that should be created is already existent!
-
 
985
 
828
        u8      retvalue = 0;
986
        // Dir entries can be created only in file-clusters that have
-
 
987
        // the dir-flag set in its attribute or within the root directory
829
        u32     cluster_temp = 0;
988
 
830
        s8 name[11]     = "           ";
989
        file->FirstSectorOfFirstCluster = 0;
831
 
990
        // no current directory exist therefore assume creating in the root
832
        SeperateFileName(fname,name);
991
        if(file->DirectorySector == 0)
Line 833... Line -...
833
 
-
 
834
        file->cluster_pointer = CWD;                                                                                            // start looking for the file in the actual directory.
-
 
835
 
-
 
836
                                                                                                                                                                // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
-
 
837
        do
-
 
838
        {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
992
        {
839
                rootentry=0;
-
 
840
                SDC_GetSector((u32) file->cluster_pointer,file->buffer);                                        // Read the Rootdirectory.
-
 
841
                DirectoryEntry = (struct DirEntry *)file->buffer;
-
 
842
 
993
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
843
                while((!retvalue)&&(rootentry<16))
994
                dircluster = 0;
844
                {
995
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
845
                        i=0;
996
        }
846
                        if(DirectoryEntry[rootentry].name[0] != 0xe5)                                                   // ignore deleted items.
-
 
847
                        {
-
 
848
                                while((i<=10)&&(DirectoryEntry[rootentry].name[i] == name[i]))
-
 
849
                                {
-
 
850
                                        i++;
-
 
851
                                }
-
 
852
                        }
997
        // within the root directory area we can read sectors sequentially until the end of this area
853
 
998
        else if((Partition.FirstRootDirSector <= file->DirectorySector) && (file->DirectorySector < Partition.FirstDataSector))
854
                        if((i==11) && (DirectoryEntry[rootentry].attribute & _FILE))            // entry found!! -> reading startcluster of entry from offset 26.
999
        {
-
 
1000
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
855
                        {
1001
        }
-
 
1002
        // within the data clusters we can read sectors sequentially only within the cluster
-
 
1003
        else if((Partition.FirstDataSector <= file->DirectorySector) && (file->DirectorySector <= Partition.LastDataSector))
856
                                cluster_temp = (u32)DirectoryEntry[rootentry].startcluster;
1004
        {
-
 
1005
                max_dir_sector = Partition.SectorsPerCluster;
857
                                cluster_temp -=2;                                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
1006
        }
858
                                cluster_temp *= (u32)SectorsPerCluster;                                                 // Calculate positon of first cluster.
1007
        else return (retvalue); // bad sector range for directory sector of the file
859
                                file->start_cluster   = (FirstDataCluster + cluster_temp);
1008
        // if search area is not defined yet
-
 
1009
        if(file->FirstSectorOfFirstCluster == 0)
-
 
1010
        {
-
 
1011
            // check if the directory entry of current file is existent and has the dir-flag set
-
 
1012
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
-
 
1013
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
860
                                file->directory_sector = (u32) file->cluster_pointer;
1014
                {
-
 
1015
                        Fat16_Deinit();
-
 
1016
                        return(retvalue);
-
 
1017
                }
-
 
1018
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
1019
                switch((uint8_t)dir[file->DirectoryIndex].Name[0])                                      // check if current directory exist
-
 
1020
                {
861
                                file->cluster_pointer = file->start_cluster;                                                            // start reading the file with the first cluster.
1021
                        case SLOT_EMPTY:
-
 
1022
                        case SLOT_DELETED:
-
 
1023
                                return (retvalue);
-
 
1024
                                break;
-
 
1025
                        default:        // and is a real directory
-
 
1026
                                if((dir[file->DirectoryIndex].Attribute & ATTR_SUBDIRECTORY) != ATTR_SUBDIRECTORY)
-
 
1027
                                {       // current file is not a directory therefore no file or subdirectory can be created here
-
 
1028
                                        return (retvalue);
-
 
1029
                                }
-
 
1030
                                break;
-
 
1031
                }
862
                                file->filesize = (u32) DirectoryEntry[rootentry].size;
1032
                dircluster = dir[file->DirectoryIndex].StartCluster;
-
 
1033
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dircluster);
-
 
1034
        }
-
 
1035
 
-
 
1036
        subdircluster = FindNextFreeCluster(file);      // get the next free cluster on the disk and mark it as used.
-
 
1037
        if(subdircluster)
863
                                file->directory_index  = (u8) rootentry;
1038
        {
-
 
1039
                file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
-
 
1040
                file->SectorOfCurrCluster               = 0;
-
 
1041
                do // loop over all clusters of current directory
-
 
1042
                {
-
 
1043
                        dir_sector = 0; // reset sector counter within a new cluster
-
 
1044
                        do // loop over all sectors of a cluster or all sectors of the root directory
-
 
1045
                        {
-
 
1046
                                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
-
 
1047
                                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
864
                                retvalue = 1;
1048
                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
1049
                                {
-
 
1050
                                        Fat16_Deinit();
-
 
1051
                                        return(retvalue);
-
 
1052
                                }
-
 
1053
                                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
1054
                                // search all directory entries of a sector
-
 
1055
                                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
-
 
1056
                                {       // check if current direntry is available
-
 
1057
                                        if(((uint8_t)dir[dir_entry].Name[0] == SLOT_EMPTY) || ((uint8_t)dir[dir_entry].Name[0] == SLOT_DELETED))
-
 
1058
                                        {       // a free direntry was found
865
                        }
1059
                                                for(i = 0; i < 11; i++) dir[dir_entry].Name[i] = dirname[i];            // Set dir name
866
                        rootentry++;
1060
                                                dir[dir_entry].Attribute    = attrib;                                                           // Set the attribute of the new directoryentry.
-
 
1061
                                                dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
867
                }
1062
                                                dir[dir_entry].DateTime         = FileDateTime(&SystemTime);                    // set date/time
868
                if(!retvalue)                                                                                   // file not found in this sector so take next sector.
1063
                                                dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
869
                {
1064
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
870
                        end_of_directory_not_reached = GetNextCluster(file);
1065
                                                {
871
                }
1066
                                                        Fat16_Deinit();
872
        }
1067
                                                        return(retvalue);
-
 
1068
                                                }
873
        while((end_of_directory_not_reached) && (!retvalue));
1069
                                                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
-
 
1070
                                                file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
874
        return(retvalue);
1071
                                                file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
-
 
1072
                                                file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
875
}
1073
                                                file->Attribute                                 = attrib;                                               // set file attribute to dir attribute
876
 
1074
                                                file->Size                                              = 0;                                                        // new file has no size
877
 
-
 
878
 
1075
                                                file->DirectorySector                   = curr_sector;
879
//________________________________________________________________________________________________________________________________________
1076
                                                file->DirectoryIndex                    = dir_entry;
880
// Funtion:     void SeperateFileName(u8*);
1077
                                                if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)                           // if a new directory was created then initilize the data area
881
//
-
 
-
 
1078
                                                {
882
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST    TXT');
1079
                                                        ClearCurrCluster(file); // fill cluster with zeros
-
 
1080
                                                        file->SectorInCache = file->FirstSectorOfFirstCluster;
-
 
1081
                                                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
883
//
1082
                                                        {
884
//________________________________________________________________________________________________________________________________________
1083
                                                                Fat16_Deinit();
885
 
1084
                                                                return(retvalue);
-
 
1085
                                                        }
-
 
1086
                                                        dir = (DirEntry_t *)file->Cache;
-
 
1087
                                                        // create direntry "." to current dir
-
 
1088
                                                        dir[0].Name[0] = 0x2E;
-
 
1089
                                                        for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
-
 
1090
                                                        dir[0].Attribute = ATTR_SUBDIRECTORY;
-
 
1091
                                                        dir[0].StartCluster = subdircluster;
-
 
1092
                                                        dir[0].DateTime = 0;
-
 
1093
                                                        dir[0].Size = 0;
-
 
1094
                                                        // create direntry ".." to the upper dir
-
 
1095
                                                        dir[1].Name[0] = 0x2E;
-
 
1096
                                                        dir[1].Name[1] = 0x2E;
-
 
1097
                                                        for(i = 2; i < 11; i++) dir[1].Name[i] = ' ';
-
 
1098
                                                        dir[1].Attribute = ATTR_SUBDIRECTORY;
-
 
1099
                                                        dir[1].StartCluster = dircluster;
-
 
1100
                                                        dir[1].DateTime = 0;
-
 
1101
                                                        dir[1].Size = 0;
-
 
1102
                                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
1103
                                                        {
-
 
1104
                                                                Fat16_Deinit();
-
 
1105
                                                                return(retvalue);
-
 
1106
                                                        }
-
 
1107
                                                }
-
 
1108
                                                retvalue = 1;
-
 
1109
                                                dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
-
 
1110
                                        }
-
 
1111
                                }
-
 
1112
                                dir_sector++; // search next sector
-
 
1113
                        // stop if we reached the end of the cluster or the end of the root dir
-
 
1114
                        }while((dir_sector < max_dir_sector) && (!retvalue));
-
 
1115
 
-
 
1116
                        // if we are seaching in the data area and the file not found in this cluster so take next cluster.
-
 
1117
                        if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
-
 
1118
                        {
886
void SeperateFileName(s8 *fname, s8 *name)
1119
                                end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
-
 
1120
                        }
887
{
1121
                }while((end_of_directory_not_reached) && (!retvalue));
-
 
1122
                // Perhaps we are at the end of the last cluster of a directory file an have no free direntry found.
-
 
1123
                // Then we would need to add a cluster to that file and create the new direntry there.
-
 
1124
                // This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
888
        u8 readpointer  = 0;
1125
                // within a subdirectory of root.
889
        u8 writepointer = 0;
1126
        }
890
        u8 attribute    = 1;
1127
        return(retvalue);       // return 1 if file has been created otherwise return 0.
891
        u8 i = 0;
1128
}
892
 
1129
 
893
 
1130
/********************************************************************************************************************************************/
894
        while((writepointer<=10) && (fname[readpointer]!=0))    // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
1131
/*      Function:               FileExist(const int8_t* filename, uint8_t attribfilter, uint8_t attribmask, File_t *file);                                                                                      */
895
        {                                                                                                               // the filename in the rootdirectory is in the format "TEST    TXT" without the dot.
1132
/*                                                                                                                                                                                                                                                                                      */
896
                if(fname[readpointer]=='.')                                             // seperating filename and attribute.
-
 
897
                {
-
 
898
                        if(attribute)                                                                   // is the filename "." or ".." ?
1133
/*      Description:    This function looks for the specified file including its subdirectories beginning                                                                               */
899
                        {
1134
/*                                      in the rootdirectory of the drive. If the file is found the Filepointer properties are                                                                  */
900
                                name[writepointer] = fname[readpointer];
1135
/*                                      updated.                                                                                                                                                                                                                                */
901
                                readpointer++;
1136
/*                                                                                                                                                                                                                                                                                      */
902
                                writepointer++;
-
 
903
                        }
-
 
904
                        else
-
 
905
                        {
-
 
906
                                if(fname[(readpointer-1)] != '*')
-
 
907
                                {
-
 
908
                                        for(i=writepointer;i<8;i++)
-
 
909
                                        {
-
 
910
                                                name[i] = ' ';
-
 
911
                                        }
-
 
912
                                }
-
 
913
                                readpointer++;
1137
/*      Returnvalue:    1 if file is found else 0.                                                                                                                                                                                              */
914
                                writepointer = 8;
-
 
915
                        }
-
 
916
                }
-
 
917
                else if(fname[readpointer] == '*')                                      // wildcard found within the filename + extension.
-
 
918
                {
-
 
919
                        if(writepointer < 8)                                            // in extension.
-
 
920
                        {
-
 
921
                                readpointer++;
-
 
922
                                writepointer = 8;
1138
/********************************************************************************************************************************************/
923
                        }
1139
uint8_t FileExist(const int8_t* filename, const uint8_t attribfilter, const uint8_t attribmask, File_t *file)
924
                        else                                                                            // in filename.
-
 
925
                        {
-
 
926
                                writepointer = 11;                                              // jump to the end of the string to terminate this function.
-
 
927
                        }
-
 
928
                        attribute = 0;
-
 
929
                }
-
 
930
                else
-
 
931
                {
-
 
932
                        if((fname[readpointer]>96) && (fname[readpointer]<123))
-
 
933
                        {
-
 
934
                                name[writepointer]=(fname[readpointer] - 32);                                   // all characters must be upper case.
-
 
935
                        }
-
 
936
                        else
-
 
937
                        {
1140
{
-
 
1141
        int8_t* path = 0;
-
 
1142
        int8_t* subpath = 0;
938
                                name[writepointer]=fname[readpointer];
1143
        uint8_t af, am, file_exist = 0;
939
                        }
1144
        int8_t  dirname[12]; // 8+3 + temination character
940
                        readpointer++;
1145
 
Line 941... Line 1146...
941
                        writepointer++;
1146
        // if incomming pointers are useless return immediatly
942
                        attribute = 0;
1147
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return 0;
943
                }
-
 
-
 
1148
 
944
        }
1149
        // trace along the filepath
945
}
-
 
946
 
-
 
-
 
1150
        path = (int8_t*)filename;                                                               // start a the beginning of the filename string
-
 
1151
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
947
//________________________________________________________________________________________________________________________________________
1152
        file->DirectoryIndex = 0;
948
// Funtion:     File * ReserveFilePointer_(void);
-
 
-
 
1153
        // as long as the file was not found and the remaining path is not empty
949
//
1154
        while((*path != 0) && !file_exist)
950
// Description: This function looks for a free filepointer and reserves it.
-
 
951
//
1155
        {       // separate dirname and subpath from filepath string
952
//
1156
                subpath = SeperateDirName(path, dirname);
953
//      Return:         NULL = faild to reserve a filepointer
1157
                if(subpath != NULL)
-
 
1158
                {
-
 
1159
                        if(*subpath == 0)
-
 
1160
                        {       // empty subpath indicates last element of dir chain
Line -... Line 1161...
-
 
1161
                                af = attribfilter;
-
 
1162
                                am = attribmask;
-
 
1163
                        }
-
 
1164
                        else  // it must be a subdirectory and no volume label
954
//                              otherwise filepointer
1165
                        {
-
 
1166
                                af = ATTR_SUBDIRECTORY;
-
 
1167
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;
-
 
1168
                        }
-
 
1169
                        if(!DirectoryEntryExist(dirname, af, am, file))
-
 
1170
                        {
-
 
1171
                                return (file_exist); // subdirectory does not exist
-
 
1172
                        }
955
//________________________________________________________________________________________________________________________________________
1173
                        else
-
 
1174
                        {
-
 
1175
                                if (*subpath == 0)
-
 
1176
                                {
956
 
1177
                                        file_exist = 1; // last element of path chain was found with the given attribute filter
-
 
1178
                                }
-
 
1179
                        }
957
File * ReserveFilePointer(void)
1180
                }
-
 
1181
                else // error seperating the subpath
958
{
1182
                {
959
        File *file;
1183
                        return file_exist; // bad subdir format
-
 
1184
                }
-
 
1185
                path = subpath;
-
 
1186
                subpath = 0;
-
 
1187
        }
-
 
1188
        return (file_exist);
-
 
1189
}
960
        file = NULL;
1190
 
-
 
1191
 
961
        u8      temp;
1192
/********************************************************************************************************************************************/
962
 
-
 
963
        for(temp = 0;temp<__MAX_FILES_USED;temp++)
-
 
964
        {
-
 
965
                if(FilePointer[temp].state == _UNUSED)                                                                          // free filepointer found?
-
 
966
                {
1193
/*      Function:               FileCreate(const s8* filename, u8 attrib, File_t *file);                                                                                                                                */
967
                        file = &FilePointer[temp];
-
 
968
                        FilePointer[temp].state                                 = _USED;                                                // mark as used.
-
 
969
                        FilePointer[temp].mode                                  = 0;                                                    // type of access (read/write) not defined yet.
-
 
970
                        FilePointer[temp].start_cluster                 = 0;                                                    // Sectorpointer to the first sector of the first datacluster of the file.
-
 
971
                        FilePointer[temp].cluster_pointer               = 0;                                                    // Pointer to the cluster which is edited at the moment.
-
 
972
                        FilePointer[temp].sector_index                  = 0;                                                    // The sector which is edited at the moment (cluster_pointer + sector_index).
-
 
973
                        FilePointer[temp].byte_index                    = 0;                                                    // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
1194
/*                                                                                                                                                                                                                                                                                      */
974
                        FilePointer[temp].filesize                              = 0;                                                    // the size of the opend file in bytes.
1195
/*      Description:    This function looks for the specified file including its subdirectories beginning                                                                               */
975
                        FilePointer[temp].fileposition                  = 0;                                                    // pointer to a character within the file 0 < fileposition < filesize
1196
/*                                      in the rootdirectory of the partition. If the file is found the Filepointer properties are                                                              */
976
                        FilePointer[temp].sector_in_buffer              = 0;                                                    // the last sector read, wich is still in the sectorbuffer.
1197
/*                                      updated. If file or its subdirectories are not found they will be created                                                                                               */
977
                        FilePointer[temp].directory_sector              = 0;                                                    // the sectorposition where the directoryentry has been made.
-
 
978
                        FilePointer[temp].directory_index               = 0;                                                    // the index to the directoryentry within the specified sector.
-
 
979
                        FilePointer[temp].attribute                     = 0;                                                    // the attribute of the file opened.
1198
/*                                                                                                                                                                                                                                                                                      */
-
 
1199
/*      Returnvalue:    1 if file was created else 0.                                                                                                                                                                                   */
980
                        break;
1200
/********************************************************************************************************************************************/
981
                }
-
 
982
        }
-
 
983
        return(file);
1201
uint8_t FileCreate(const int8_t* filename, const uint8_t attrib, File_t *file)
984
}
1202
{
Line 985... Line -...
985
 
-
 
986
 
-
 
987
//________________________________________________________________________________________________________________________________________
1203
        int8_t *path = 0;
-
 
1204
        int8_t *subpath = 0;
988
// Funtion:     void FreeFilePointer_(File *);
1205
        uint8_t af, am, file_created = 0;
989
//
-
 
990
// Description: This function free's the filepointer by marking it as unused.
1206
        int8_t dirname[12];
991
//
-
 
992
//
-
 
-
 
1207
 
-
 
1208
        // if incomming pointers are useless return immediatly
993
//      Return:         none
1209
        if ((filename == NULL) || (file == NULL) || (!Partition.IsValid)) return 0;
994
//
1210
 
995
//________________________________________________________________________________________________________________________________________
-
 
996
 
1211
        // trace along the filepath
997
void FreeFilePointer(File *file)
1212
        path = (int8_t*)filename;                                                                       // start a the beginning of the filename string
998
{
-
 
999
        u8 cnt = 0;
-
 
1000
 
-
 
1001
        for(cnt=0;cnt<__MAX_FILES_USED;cnt++)                                                                                   // Is the filepointeradress vaild?
-
 
1002
        {
-
 
1003
                if(&FilePointer[cnt] == file)                                                                                           // filepointer found therefore it must be valid
-
 
1004
                {
-
 
1005
                        FilePointer[cnt].state = _UNUSED;                                                                               // and can be marked as unused.
1213
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1006
                }
-
 
Line 1007... Line 1214...
1007
        }
1214
        file->DirectoryIndex = 0;
1008
}
-
 
Line 1009... Line 1215...
1009
 
1215
        // as long as the file was not created and the remaining file path is not empty
1010
 
-
 
1011
//________________________________________________________________________________________________________________________________________
1216
        while((*path != 0) && !file_created)
1012
// Funtion:     void DelteDirectoryEntry(Find *)
-
 
1013
//
1217
        {   // separate dirname and subpath from filepath string
1014
// Description: This function deletes the directoryentry of the specified item.
1218
                subpath = SeperateDirName(path, dirname);
1015
//
-
 
Line -... Line 1219...
-
 
1219
                if(subpath != NULL)
-
 
1220
                {
-
 
1221
                        if(*subpath == 0)
1016
//
1222
                        {       // empty subpath indicates last element of dir chain
-
 
1223
                                af = ATTR_NONE;
-
 
1224
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;  // any file that is no subdir or volume label
-
 
1225
                        }
-
 
1226
                        else  // it must be a subdirectory and no volume label
-
 
1227
                        {
-
 
1228
                                af = ATTR_SUBDIRECTORY;
-
 
1229
                                am = ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL;
-
 
1230
                        }
-
 
1231
                        if(!DirectoryEntryExist(dirname, af, am, file)) // if subdir or file is not existent
-
 
1232
                        {  // try to create subdir or file
-
 
1233
                                if(*subpath == 0) af = attrib; // if last element in dir chain take the given attribute
-
 
1234
                                if(!CreateDirectoryEntry(dirname, af, file))
1017
// returnvalue: 1 if the directory could be created.
1235
                                {       // could not be created
-
 
1236
                                        return(file_created);
1018
//________________________________________________________________________________________________________________________________________
1237
                                }
-
 
1238
                                else if (*subpath == 0) file_created = 1; // last element of path chain was created
-
 
1239
                        }
1019
 
1240
                }
-
 
1241
                else // error seperating the subpath
-
 
1242
                {
1020
void DeleteDirectoryEntry(Find *item)
1243
                        return file_created; // bad subdir format
1021
{
-
 
1022
        u8 buffer[512];
1244
                }
-
 
1245
                path = subpath;
1023
 
1246
                subpath = 0;
1024
 
1247
        }
1025
        SDC_GetSector((u32) item->cluster_pointer,buffer);                                                              // Read the Rootdirectory.
-
 
1026
        DirectoryEntry = (struct DirEntry *)buffer;
-
 
1027
 
1248
        return (file_created);
1028
        DirectoryEntry[(item->directory_index)-1].attribute = 0;                                                        // free the directoryentry.
1249
}
1029
        DirectoryEntry[(item->directory_index)-1].name[0] = 0xE5;                                                       // free the directoryentry.
1250
 
1030
        SDC_PutSector((u32) item->cluster_pointer,buffer);                                                              // Read the Rootdirectory.
-
 
1031
}
1251
 
1032
 
1252
/********************************************************************************************************************************************/
1033
 
-
 
1034
 
1253
/*      Function:               File_t * fopen_(int8_t* filename, int8_t mode);                                                                                                                                                                 */
1035
 
-
 
1036
//________________________________________________________________________________________________________________________________________
-
 
1037
// Funtion:     u8 CreateSubDirectory(u8 *)
1254
/*                                                                                                                                                                                                                                                                                      */
1038
//
1255
/*      Description:    This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the    */
1039
// Description: This function creates an directory within the directory specified by CWD
-
 
1040
//
1256
/*                                      corrosponding filepointer is returned. Only modes 'r' (reading) and 'a' append are implemented yet.                                             */
1041
//
1257
/*                                                                                                                                                                                                                                                                                      */
1042
// returnvalue: 1 if the directory could be created.
-
 
1043
//________________________________________________________________________________________________________________________________________
1258
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1044
 
-
 
1045
u8 CreateSubDirectory(s8 *fname)
-
 
1046
{
-
 
1047
        u16     index   = 0;                                                                                                                            // index to an entry in the rootdirectory.
-
 
1048
        u16     cnt_entries_searched = 0;                                                                                                               // count the number of rootentries which have been searched already.
-
 
1049
        u16             i = 0;
-
 
1050
        u16     sector_offset = 0;                                                                                                                              // index to the sector of the entry which is searched momentarily
1259
/********************************************************************************************************************************************/
1051
        u8              retvalue = 0;
-
 
1052
        u32             cluster_temp = 0;
1260
File_t * fopen_(const int8_t *filename, const int8_t mode)
1053
        u16             cluster = 0;
1261
{
1054
        File    file;
1262
        File_t *file    = 0;
1055
        u8              name[11] = {"           "};
-
 
1056
 
-
 
1057
        SeperateFileName(fname,name);
-
 
1058
        cluster_temp = (u32)FindNextFreeCluster(&file);                                                                         // the next free cluster on the disk.
-
 
1059
 
-
 
1060
        if(cluster_temp)                                                                                                                                                // if a free cluster is available:
-
 
1061
        {
-
 
1062
                cluster = (u16)cluster_temp;                                                                                                            // remember the index of the free datacluster found for the directory entry.
1263
 
1063
                cluster_temp -=2;                                                                                                                                       // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
1264
        if((!Partition.IsValid) || (filename == 0)) return(file);
1064
                cluster_temp *= SectorsPerCluster;                                                                                                      // Calculate relative sectorindex of first datacluster.
1265
 
1065
                file.start_cluster   = (FirstDataCluster + cluster_temp);                                                       // Calculate absolute sectorposition of first datacluster.
1266
        // Look for an unused filepointer in the file pointer list?
1066
                file.cluster_pointer = file.start_cluster;                                                                                      // start reading the file with the first sector of the first datacluster.
1267
        file = LockFilePointer();
1067
 
1268
        // if no unused file pointer was found return 0
-
 
1269
        if(file == NULL) return(file);
-
 
1270
 
1068
// -Initialise new cluster to zero--------------------------------------------------------
1271
        // now we have found a free filepointer and claimed it
-
 
1272
        // so let initiate its property values
-
 
1273
        file->FirstSectorOfFirstCluster = 0;            // Sectorpointer to the first sector of the first datacluster of the file.
-
 
1274
        file->FirstSectorOfCurrCluster  = 0;            // Pointer to the cluster which is edited at the moment.
-
 
1275
        file->SectorOfCurrCluster               = 0;            // The sector which is edited at the moment (cluster_pointer + sector_index).
-
 
1276
        file->ByteOfCurrSector                  = 0;            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
-
 
1277
        file->Mode                                              = mode;         // mode of fileoperation (read,write)
-
 
1278
        file->Size                                              = 0;            // the size of the opened file in bytes.
1069
                for(i=0;i<512;i++)
1279
        file->Position                                  = 0;            // pointer to a byte within the file 0 < fileposition < filesize
1070
                {
1280
        file->SectorInCache                             = 0;            // the last sector read, wich is still in the sectorbuffer.
1071
                        file.buffer[i] = 0;                                                                                                                             // initialise buffer to zero
1281
        file->DirectorySector                   = 0;            // the sectorposition where the directoryentry has been made.
-
 
1282
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
-
 
1283
        file->Attribute                                 = 0;            // the attribute of the file opened.
1072
                }
1284
 
-
 
1285
        // check if a real file (no directory) to the given filename exist
-
 
1286
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
-
 
1287
        {  // file exist
-
 
1288
                switch(mode)  // check mode
1073
                for(sector_offset=0;sector_offset<SectorsPerCluster;sector_offset++)                            // initialise all sectors of new cluster with buffer.
1289
                {
-
 
1290
                        case 'a':       // if mode is: append to file
1074
                {
1291
                                if((file->Attribute & ATTR_READONLY) == ATTR_READONLY)
-
 
1292
                                {       // file is marked as readonly --> do not open this file
-
 
1293
                                        fclose_(file);
-
 
1294
                                        file = NULL;
-
 
1295
                                }
-
 
1296
                                else
-
 
1297
                                {       // file is not marked as read only --> goto end of file
1075
                        SDC_PutSector((u32)(file.start_cluster + sector_offset),file.buffer);                   // save the initialised sector to the card.
1298
                                        fseek_(file, 0, SEEK_END);              // point to the end of the file
1076
                }
1299
                                }
1077
// -Create directoryentry "." -------------------------------------------------------------
-
 
1078
                DirectoryEntry = (struct DirEntry *)file.buffer;
1300
                                break;
1079
                DirectoryEntry[0].name[0] = '.';
1301
                        case 'w':       // if mode is: write to file
-
 
1302
                                if((file->Attribute & ATTR_READONLY) == ATTR_READONLY)
-
 
1303
                                {       // file is marked as readonly --> do not open this file
-
 
1304
                                        fclose_(file);
1080
                DirectoryEntry[0].attribute = _DIRECTORY;
1305
                                        file = NULL;
Line -... Line 1306...
-
 
1306
                                }
-
 
1307
                                else
-
 
1308
                                {       // file is not marked as read only --> goto start of file
-
 
1309
                                        // free all clusters of that file
-
 
1310
                                        DeleteClusterChain(SectorToFat16Cluster(file->FirstSectorOfFirstCluster));
-
 
1311
                                        // mar an empy cluster as the last one and store the corresponding sector
-
 
1312
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(FindNextFreeCluster(file));
-
 
1313
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
-
 
1314
                                        file->SectorOfCurrCluster = 0;
-
 
1315
                                        file->ByteOfCurrSector = 0;
Line 1081... Line -...
1081
                DirectoryEntry[0].startcluster = cluster;
-
 
1082
// -Create directoryentry "." -------------------------------------------------------------
-
 
1083
                DirectoryEntry[1].name[0] = '.';
-
 
1084
                DirectoryEntry[1].name[1] = '.';
-
 
1085
                DirectoryEntry[1].attribute = _DIRECTORY;
-
 
1086
                if(CWD == RootDirectory)
-
 
1087
                {
-
 
1088
                        DirectoryEntry[1].startcluster = 0;
-
 
1089
                }
-
 
1090
                else
-
 
1091
                {
-
 
1092
                        cluster_temp = (CWD - FirstDataCluster);
-
 
1093
                        cluster_temp /= SectorsPerCluster;
-
 
1094
                        cluster_temp -= 2;
-
 
1095
                        DirectoryEntry[1].startcluster = (u16) cluster_temp;
-
 
1096
                }
-
 
1097
                SDC_PutSector((u32) file.start_cluster,file.buffer);                                                                                    // save the initialised sector to the card.
-
 
1098
// -create directoryentry within the cwd --------------------------------------------------
-
 
1099
                sector_offset = 0;
-
 
1100
                cnt_entries_searched = 0;
-
 
1101
                do
-
 
1102
                {                                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
-
 
1103
                        index=0;
-
 
1104
                        SDC_GetSector((u32)(CWD + sector_offset),file.buffer);                                                  // Read the actual directory.
-
 
1105
                        DirectoryEntry = (struct DirEntry *)file.buffer;
-
 
1106
                        while((index<16) && (!retvalue))
-
 
1107
                        {
-
 
1108
                                if((DirectoryEntry[index].attribute == 0) || (DirectoryEntry[index].attribute == 0xE5)) // empty directory entry found
1316
                                        file->Size = 0;
Line 1109... Line 1317...
1109
                                {
1317
                                        file->Position = 0;
1110
                                        for(i=0;i<11;i++) DirectoryEntry[index].name[i] = name[i];              // Kopie the filename and the file extension to the directoryentry.
1318
                                        fseek_(file, 0, SEEK_SET);
-
 
1319
                                }
1111
                                        DirectoryEntry[index].attribute    = _DIRECTORY;                                        // Set the fileattribute to archive to reserve the directoryentry.
1320
                                break;
1112
                                        DirectoryEntry[index].startcluster = cluster;                                           // copy the location of the first datacluster to the directoryentry.
1321
                        case 'r':       // if mode is: read from file
1113
                                        DirectoryEntry[index].size     = 0;                                                                     // the new createted file has no content yet.
1322
                                // goto end of file
1114
                                        file.directory_sector = (u32) (CWD + sector_offset);
1323
                                fseek_(file, 0, SEEK_SET);
1115
                                        file.directory_index  = (u8) index;
1324
                                break;
-
 
1325
                        default: // other modes are not supported
1116
                                        retvalue = 1;
1326
                                fclose_(file);
1117
                                        SDC_PutSector((u32)(CWD + sector_offset),file.buffer);
1327
                                file = NULL;
1118
                                }
1328
                        break;
1119
                                index++;
-
 
-
 
1329
                }
1120
                                cnt_entries_searched++;
1330
                return(file);
1121
                        }
1331
        }
1122
                        if(!retvalue)                                                                                                                                   // file not found in this sector so take next sector.
1332
        else // file does not exist
1123
                        {
-
 
1124
                                index = 0;
1333
        {
1125
                                sector_offset++;
1334
                switch(mode)  // check mode
-
 
1335
                {
-
 
1336
                        case 'a':
-
 
1337
                        case 'w': // if mode is write or append
-
 
1338
                                // try to create the file
1126
                        }
1339
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1127
                }
1340
                                { // if it could not be created
1128
                while((cnt_entries_searched< PossibleRootEntries) && (!retvalue));
1341
                                        fclose_(file);
-
 
1342
                                        file = NULL;
1129
 
1343
                                }
-
 
1344
                                break;
-
 
1345
                        case 'r': // else opened for 'r'
-
 
1346
                        default:  // of unsupported mode
-
 
1347
                                fclose_(file);
-
 
1348
                                file = NULL;
-
 
1349
                                break;
1130
        }
1350
                }
1131
        return(retvalue);                                                                                                                                       // return 1 if file has been created otherwise return 0.
-
 
1132
}
1351
                return(file);
1133
 
1352
        }
Line -... Line 1353...
-
 
1353
        // we should never come to this point
-
 
1354
        fclose_(file);
-
 
1355
        file = NULL;
-
 
1356
        return(file);
-
 
1357
}
-
 
1358
 
-
 
1359
/****************************************************************************************************************************************************/
-
 
1360
/* Function:    fflush_(File *);                                                                                                                                                                                                                                        */
-
 
1361
/*                                                                                                                                                                                                                                                                                                      */
-
 
1362
/* Description: This function writes the data already in the buffer but not yet written to the file.                                                                                            */
-
 
1363
/*                                                                                                                                                                                                                                                                                                      */
-
 
1364
/* Returnvalue: 0 on success EOF on error                                                                                                                                                                                                                       */
-
 
1365
/****************************************************************************************************************************************************/
-
 
1366
int16_t fflush_(File_t *file)
-
 
1367
{
-
 
1368
        DirEntry_t *dir;
-
 
1369
 
-
 
1370
        if((file == NULL) || (!Partition.IsValid)) return (EOF);
-
 
1371
 
-
 
1372
        switch(file->Mode)
-
 
1373
        {
-
 
1374
                case 'a':
-
 
1375
                case 'w':
-
 
1376
                        if(file->ByteOfCurrSector > 0)                                                                          // has data been added to the file?
-
 
1377
                        {
-
 
1378
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// save the data still in the buffer
-
 
1379
                                {
-
 
1380
                                        Fat16_Deinit();
-
 
1381
                                        return(EOF);
-
 
1382
                                }
-
 
1383
                        }
-
 
1384
                        file->SectorInCache     = file->DirectorySector;
-
 
1385
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))                                       // read the directory entry for this file.
-
 
1386
                        {
-
 
1387
                                Fat16_Deinit();
-
 
1388
                                return(EOF);
-
 
1389
                        }
Line -... Line 1390...
-
 
1390
 
1134
 
1391
                        dir = (DirEntry_t *)file->Cache;
1135
//________________________________________________________________________________________________________________________________________
-
 
1136
// Funtion:     u16 SeekSubDirectory(s8 *fname)
1392
                        dir[file->DirectoryIndex].Size = file->Size;                                            // update file size
-
 
1393
                        dir[file->DirectoryIndex].DateTime = FileDateTime(&SystemTime);         // update date time
1137
//
1394
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to sd-card
1138
// Description: looks for the specified directory within the CWD.
1395
                        {
-
 
1396
                                Fat16_Deinit();
1139
//
1397
                                return(EOF);
1140
// Returnvalue: If the specified directory was found the startcluster is returned. otherwise 0.
1398
                        }
1141
//________________________________________________________________________________________________________________________________________
1399
                        break;
-
 
1400
                case 'r':
-
 
1401
                default:
1142
 
1402
                        return(EOF);
1143
u16 SeekSubDirectory(s8 *fname)
1403
                        break;
-
 
1404
 
1144
{
1405
        }
-
 
1406
        return(0);
1145
        u16     index = 0;
1407
}
1146
        u16     end_of_directory_not_reached = 0;                                                                       // the directory has been read completely without a result.
-
 
1147
        u8              i = 0;
-
 
1148
        u16     cluster_temp = 0;
-
 
Line 1149... Line 1408...
1149
        s8 name[11]     = "           ";
1408
 
1150
        File    file;
1409
/****************************************************************************************************************************************/
1151
 
1410
/*      Function:               fclose_(File *file);                                                                                                                                                                                            */
1152
        SeperateFileName(fname,name);
-
 
1153
 
1411
/*                                                                                                                                                                                                                                                                              */
1154
        file.cluster_pointer = CWD;                                                                                                     // start looking for the file in the actual directory.
1412
/*      Description:    This function closes the open file by writing the remaining data                                                                                                        */
1155
        file.start_cluster   = CWD;                                                                                                     // start looking for the file in the actual directory.
1413
/*                                      from the buffer to the device and entering the filesize in the directory entry.                                                                         */
1156
 
1414
/*                                                                                                                                                                                                                                                                              */
-
 
1415
/*      Returnvalue:    0 on success EOF on error                                                                                                                                                                                       */
1157
                                                                                                                                                                // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
1416
/****************************************************************************************************************************************/
1158
        do
-
 
1159
        {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
-
 
1160
                index=0;
1417
int16_t fclose_(File_t *file)
1161
                SDC_GetSector((u32) file.cluster_pointer,file.buffer);                                  // Read the Rootdirectory.
-
 
1162
                DirectoryEntry = (struct DirEntry *)file.buffer;
-
 
1163
 
-
 
1164
                while((!cluster_temp)&&(index<16))
-
 
1165
                {
-
 
1166
                        i=0;
-
 
1167
                        if(DirectoryEntry[index].name[0] != 0xe5)                                                       // ignore deleted items.
-
 
1168
                        {
-
 
1169
                                while((i<=10)&&(DirectoryEntry[index].name[i] == name[i]))
-
 
1170
                                {
-
 
1171
                                        i++;
-
 
1172
                                }
-
 
1173
                        }
-
 
1174
 
-
 
1175
                        if((i==11) && (DirectoryEntry[index].attribute & _DIRECTORY))   // entry found!! -> reading startcluster of entry from offset 26.
-
 
1176
                        {
-
 
1177
                                cluster_temp = (u16)DirectoryEntry[index].startcluster;
-
 
1178
                        }
-
 
1179
                        index++;
-
 
1180
                }
-
 
1181
                if(!cluster_temp)                                                                                       // file not found in this sector so take next sector.
-
 
1182
                {
-
 
1183
                        end_of_directory_not_reached = GetNextCluster(&file);
-
 
1184
                }
-
 
1185
        }
-
 
1186
        while((end_of_directory_not_reached) && (!cluster_temp));
-
 
1187
        return(cluster_temp);
-
 
1188
}
-
 
1189
 
1418
{
1190
 
-
 
1191
 
-
 
1192
//________________________________________________________________________________________________________________________________________
-
 
1193
// Funtion:     u8 mkdir_(u8 *)
-
 
1194
//
1419
        int16_t returnvalue = EOF;
1195
// Description: This function checks if the directory to be created already exists. If not the directory will be created.
-
 
1196
//
1420
 
1197
//
1421
        if(file == NULL) return(returnvalue);
Line -... Line 1422...
-
 
1422
        returnvalue = fflush_(file);
-
 
1423
        UnlockFilePointer(file);
-
 
1424
        return(returnvalue);
-
 
1425
}
-
 
1426
 
-
 
1427
/********************************************************************************************************************************************/
-
 
1428
/*      Function:               fgetc_(File *file);                                                                                                                                                                                                             */
-
 
1429
/*                                                                                                                                                                                                                                                                                      */
-
 
1430
/*      Description:    This function reads and returns one character from the specified file. Is the end of the actual sector reached the              */
-
 
1431
/*                                      next sector of the cluster is read. If the last sector of the cluster read the next cluster will be searched in FAT.    */
-
 
1432
/*                                                                                                                                                                                                                                                                                      */
Line 1198... Line -...
1198
// returnvalue: 1 if the directory could be created.
-
 
1199
//________________________________________________________________________________________________________________________________________
-
 
1200
 
-
 
1201
u8      mkdir_(s8 *fname)
-
 
1202
{
-
 
1203
        u8 retvalue = 0;
-
 
1204
 
-
 
1205
        retvalue = SeekSubDirectory(fname);                                                                                     // check wether the specified directory already exists.
-
 
1206
 
-
 
1207
        if(!retvalue)
-
 
1208
        {
-
 
1209
                CreateSubDirectory(fname);                                                                                              // if directory doesn't exist, create it.
-
 
1210
                retvalue = 1;
-
 
1211
        }
-
 
1212
        else
-
 
1213
        {
-
 
1214
                retvalue = 0;
-
 
1215
        }
-
 
1216
 
-
 
1217
        return(retvalue);
-
 
1218
}
1433
/*      Returnvalue:    The function returns the character read from the specified memorylocation as u8 casted to s16 or EOF.                                   */
1219
 
-
 
1220
 
-
 
1221
//________________________________________________________________________________________________________________________________________
-
 
1222
// Funtion:     u8 chdir_(u8 *)
-
 
1223
//
-
 
1224
// Description: This function changes the CWD to the directory specified.
-
 
Line -... Line 1434...
-
 
1434
/********************************************************************************************************************************************/
-
 
1435
int16_t fgetc_(File_t *file)
1225
//
1436
{
-
 
1437
        int16_t c = EOF;
1226
//
1438
        uint32_t curr_sector;
-
 
1439
 
1227
// returnvalue: 1 if the directory could be changed.
1440
        if( (!Partition.IsValid) || (file == NULL)) return(c);
-
 
1441
        // if the end of the file is not reached, get the next character.
1228
//________________________________________________________________________________________________________________________________________
1442
        if((0 < file->Size) && ((file->Position+1) < file->Size) )
-
 
1443
        {
-
 
1444
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
1229
 
1445
                curr_sector += file->SectorOfCurrCluster;
-
 
1446
 
1230
u8      chdir_(s8 *fname)
1447
                if(file->SectorInCache != curr_sector)
1231
{
1448
                {
-
 
1449
                        file->SectorInCache = curr_sector;
1232
        u8      retvalue = 0;
1450
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache,file->Cache))
1233
        u8  name[11] = {"           "};
1451
                        {
1234
 
1452
                                Fat16_Deinit();
Line -... Line 1453...
-
 
1453
                                return(c);
-
 
1454
                        }
-
 
1455
                }
-
 
1456
                c = (int16_t) file->Cache[file->ByteOfCurrSector];
-
 
1457
                file->Position++;                                                                       // increment file position
-
 
1458
                file->ByteOfCurrSector++;                                                       // goto next byte in sector
1235
        u32 ultemp = 0;
1459
                if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if end of sector
1236
 
1460
                {
1237
        SeperateFileName(fname,name);
-
 
1238
 
-
 
1239
        ultemp = (u32)SeekSubDirectory(name);
-
 
1240
        if(ultemp >= 2)
1461
                        file->ByteOfCurrSector = 0;                                             //  reset byte location
1241
        {
-
 
1242
                ultemp -=2;                                                                                                                                             // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
1462
                        file->SectorOfCurrCluster++;                                    //      next sector
1243
                ultemp *= SectorsPerCluster;                                                                                                    // Calculate relative sectorindex of first datacluster.
1463
                        if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster)    // if end of cluster is reached, the next datacluster has to be searched in the FAT.
-
 
1464
                        {
-
 
1465
 
1244
                ultemp += FirstDataCluster;
1466
                                if(GetNextCluster(file))                                                                                // Sets the clusterpointer of the file to the next datacluster.
1245
                CWD = ultemp;
1467
                                {
-
 
1468
                                        file->SectorOfCurrCluster = 0;                                                          // start reading new cluster at first sector of the cluster.
1246
                retvalue = 1;
1469
                                }
-
 
1470
                                else // the last cluster was allready reached
1247
        }
1471
                                {
1248
        else
1472
                                        file->SectorOfCurrCluster--;                                                    // jump back to the last sector in the last cluster
1249
        {
-
 
1250
                CWD = RootDirectory;
-
 
1251
                retvalue = 1;
1473
                                        file->ByteOfCurrSector = BYTES_PER_SECTOR;                              // set ByteOfCurrSector one byte over sector end
1252
        }
1474
                                }
1253
 
1475
                        }
1254
        return(retvalue);
1476
                }
1255
}
-
 
1256
 
-
 
1257
 
-
 
1258
//________________________________________________________________________________________________________________________________________
1477
        }
1259
// Funtion:     u8 FindItem(s8 *fname, Find *)
-
 
1260
//
-
 
1261
// Description: finds an item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
-
 
1262
//
-
 
1263
// Returnvalue: If an item was found this function returns '1' else '0'.
1478
        return(c);
1264
//________________________________________________________________________________________________________________________________________
1479
}
1265
 
1480
 
1266
u8 FindItem(Find *item)
-
 
1267
{
1481
/********************************************************************************************************************************************/
1268
        u16     index = 0;
-
 
1269
        u16     end_of_directory_not_reached = 0;                                                                       // the directory has been read completely without a result.
-
 
1270
        u8              i = 0;
-
 
1271
        u8              readpointer = 0;
1482
/*      Function:               fputc_( const s8 c, File *file);                                                                                                                                                                                */
1272
        u8              writepointer = 0;
-
 
1273
        u8              retvalue = 0;
-
 
1274
        File    file;
-
 
1275
 
-
 
1276
 
-
 
1277
        file.cluster_pointer = item->cluster_pointer;
-
 
1278
        file.start_cluster   = item->cluster_pointer;
-
 
1279
        index                            = item->directory_index;
-
 
1280
                                                                                                                                                                // directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
-
 
1281
        do
-
 
1282
        {                                                                                                                                                       // search the next 16 rootentries in this sector of the roordirectory.
-
 
1283
                SDC_GetSector((u32) file.cluster_pointer,file.buffer);                                  // Read the Rootdirectory.
-
 
1284
                DirectoryEntry = (struct DirEntry *)file.buffer;
-
 
1285
 
1483
/*                                                                                                                                                                                                                                                                                      */
1286
                while((!retvalue)&&(index<16))
-
 
1287
                {
-
 
1288
                        i=0;
-
 
1289
                        if(DirectoryEntry[index].name[0] != 0xe5)                                                       // ignore deleted items.
-
 
1290
                        {
-
 
1291
                                while((i<=10)&&((DirectoryEntry[index].name[i] == item->searchstring[i]) || (item->searchstring[i]=='*') || item->searchstring[i]=='?'))
1484
/*      Description:    This function writes a byte to the specified file and takes care of writing the necessary FAT- Entries.                                 */
Line 1292... Line -...
1292
                                {
-
 
1293
                                        i++;
-
 
1294
                                }
-
 
1295
                        }
-
 
1296
 
-
 
Line -... Line 1485...
-
 
1485
/*                                      next sector of the cluster is read. If the last sector of the cluster read the next cluster will be searched in FAT.    */
-
 
1486
/*                                                                                                                                                                                                                                                                                      */
1297
                        if((i==11) && (DirectoryEntry[index].attribute & item->attribute))
1487
/*      Returnvalue:    The function returns the character written to the stream or EOF on error.                                                                                               */
-
 
1488
/********************************************************************************************************************************************/
-
 
1489
int16_t fputc_(const int8_t c, File_t *file)
-
 
1490
{
-
 
1491
        uint32_t curr_sector  = 0;
-
 
1492
 
-
 
1493
        if((!Partition.IsValid) || (file == NULL)) return(EOF);
1298
                        {
1494
 
-
 
1495
        // If file position equals to file size, then the end of file has reached.
-
 
1496
        // In this chase it has to be checked that the ByteOfCurrSector is BYTES_PER_SECTOR
-
 
1497
        // and a new cluster should be appended.
-
 
1498
        if((file->Position >= file->Size) && (file->ByteOfCurrSector >= BYTES_PER_SECTOR))
1299
                                for(readpointer=0;readpointer<=10;readpointer++)
1499
        {
1300
                                {
-
 
Line -... Line 1500...
-
 
1500
                if(!AppendCluster(file)) return(EOF);
Line 1301... Line -...
1301
                                        if(DirectoryEntry[index].name[readpointer] != ' ')
-
 
1302
                                        {
-
 
1303
                                                item->name[writepointer] = DirectoryEntry[index].name[readpointer];     // copy the name of the item found to the find_structure.
-
 
1304
                                                writepointer++;
-
 
1305
                                        }
-
 
1306
                                        else if((readpointer==7) && (DirectoryEntry[index].attribute == _FILE)) // if the item found is a file
1501
        }
1307
                                        {
-
 
Line 1308... Line -...
1308
                                                if(DirectoryEntry[index].name[readpointer] != ' ')
-
 
1309
                                                {
1502
 
1310
                                                        item->name[writepointer] = DirectoryEntry[index].name[readpointer];     // copy the name of the item found to the find_structure.
1503
        curr_sector  = file->FirstSectorOfCurrCluster;
1311
                                                        writepointer++;
1504
        curr_sector += file->SectorOfCurrCluster;
1312
                                                }
-
 
1313
                                                item->name[writepointer] = '.';                                         // then seperate the name and the extension by a '.' at index 8.
-
 
1314
                                                writepointer++;
1505
        if(file->SectorInCache != curr_sector)
1315
                                        }
1506
        {
1316
                                }
1507
                file->SectorInCache = curr_sector;
-
 
1508
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))
-
 
1509
                {
-
 
1510
                        Fat16_Deinit();
-
 
1511
                        return(EOF);
-
 
1512
                }
1317
                                item->startcluster = (u16)DirectoryEntry[index].startcluster;
1513
        }
-
 
1514
 
1318
                                item->directory_index = ++index;
1515
        file->Cache[file->ByteOfCurrSector] = (uint8_t)c;                       // write databyte into the buffer. The byte will be written to the device at once
1319
                                item->cluster_pointer = file.cluster_pointer;
1516
        if(file->Size == file->Position) file->Size++;          // a character has been written to the file so the size is incremented only when the character has been added at the end of the file.
-
 
1517
        file->Position++;                                                                       // the actual positon within the file.
1320
                                retvalue = 1;
1518
        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1321
                        }
1519
        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
-
 
1520
        {       // save the sector to the sd-card
-
 
1521
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1322
                        index++;
1522
                {
Line -... Line 1523...
-
 
1523
                        Fat16_Deinit();
-
 
1524
                        return(EOF);
-
 
1525
                }
-
 
1526
                file->ByteOfCurrSector = 0;                                             //  reset byte location
-
 
1527
                file->SectorOfCurrCluster++;                                    //      next sector
-
 
1528
                if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster)// if end of cluster is reached, the next datacluster has to be searched in the FAT.
-
 
1529
                {
-
 
1530
                        if(!GetNextCluster(file))                                                               // Sets the clusterpointer of the file to the next datacluster.
-
 
1531
                        { // if current cluster was the last cluster of the file
-
 
1532
                                if(!AppendCluster(file))                                                // append a new and free cluster at the end of the file.
-
 
1533
                                {
-
 
1534
                                        file->SectorOfCurrCluster--;                            // jump back to last sector of last cluster
-
 
1535
                                        file->ByteOfCurrSector = BYTES_PER_SECTOR;      // set byte location to 1 byte over sector len
-
 
1536
                                        return(EOF);
-
 
1537
                                }
Line 1323... Line -...
1323
                }
-
 
1324
                if(!retvalue)                                                                                                                   // file not found in this sector so take next sector.
-
 
1325
                {
-
 
1326
                        end_of_directory_not_reached = GetNextCluster(&file);
1538
                        }
1327
                }
-
 
1328
                index = 0;
-
 
1329
        }
-
 
Line -... Line 1539...
-
 
1539
                        else // next cluster
Line 1330... Line 1540...
1330
        while((end_of_directory_not_reached) && (!retvalue));
1540
                        {
1331
 
1541
                                file->SectorOfCurrCluster = 0;                                                  // start reading new cluster at first sector of the cluster.
1332
        return(retvalue);
1542
                        }
1333
}
-
 
1334
 
-
 
1335
 
1543
                }
1336
//________________________________________________________________________________________________________________________________________
-
 
1337
// Funtion:     u8 findfirst(s8 *fname, Find *)
-
 
1338
//
-
 
1339
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
1544
        }
1340
//
-
 
1341
// Returnvalue: If an item was found this function returns '1' else '0'.
-
 
1342
//________________________________________________________________________________________________________________________________________
-
 
1343
 
1545
        return(0);
1344
u8 findfirst_(s8 *fname, Find *item, u8 attribute)
-
 
1345
{
-
 
1346
        u8 retvalue = 0;
1546
}
1347
        u8 i = 0;
1547
 
1348
 
1548
 
1349
        for(i=0;i<=11;i++)
1549
/****************************************************************************************************************************************/
1350
        {
1550
/*      Function:               fread_(void *buffer, uint32_t size, uint32_t count, File *File);                                                                                                                                */
1351
                item->searchstring[i] = '*';                                                                                            // initialise the searchstring with wildcards.
1551
/*                                                                                                                                                                                                                                                                              */
1352
                item->name[i] = 0;
1552
/*      Description:    This function reads count objects of the specified size                                                                                                                         */
1353
        }
-
 
1354
 
1553
/*                                      from the actual position of the file to the specified buffer.                                                                                                           */
1355
        SeperateFileName(fname,item->searchstring);
1554
/*                                                                                                                                                                                                                                                                              */
1356
 
1555
/*      Returnvalue:    The function returns the number of objects (not bytes) read from the file.                                                                                      */
1357
        item->cluster_pointer = CWD;                                                                                                    // findfirst_ starts at the beginning of the cwd.
1556
/****************************************************************************************************************************************/
1358
        item->directory_index = 0;
1557
uint32_t fread_(void *buffer, uint32_t size, uint32_t count, File_t *file)
Line 1359... Line -...
1359
        item->attribute = attribute;
-
 
1360
 
-
 
1361
        retvalue = FindItem(item);
1558
{
1362
 
1559
        uint32_t object_cnt     = 0;                                                                                    // count the number of objects read from the file.
Line 1363... Line -...
1363
        return(retvalue);
-
 
1364
}
1560
        uint32_t object_size = 0;                                                                                       // count the number of bytes read from the actual object.
-
 
1561
        uint8_t *pbuff          = 0;                                                                                    // a pointer to the actual bufferposition.
1365
 
1562
        uint8_t success      = 1;                                                                                       // no error occured during read operation to the file.
1366
 
-
 
1367
//________________________________________________________________________________________________________________________________________
1563
        int16_t c;
1368
// Funtion:     u8 findnext(Find *)
-
 
1369
//
1564
 
-
 
1565
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
1370
// Description: finds the first item (file or directory) within common working directory (cwd). Wildcards '*' or '?' will be considered.
1566
 
1371
//
-
 
1372
// Returnvalue: If an item was found this function returns '1' else '0'.
-
 
1373
//________________________________________________________________________________________________________________________________________
1567
        pbuff = (uint8_t *) buffer;                                                                                     // cast the void pointer to an u8 *
1374
 
1568
 
1375
 
1569
        while((object_cnt < count) && success)
1376
u8 findnext_(Find *item)
1570
        {
Line 1377... Line -...
1377
{
-
 
1378
        u8 retvalue = 0;
1571
                object_size = size;
Line 1379... Line 1572...
1379
        u8 i = 0;
1572
                while((size > 0) && success)
1380
 
1573
                {
1381
        for(i=0;i<=11;i++)
1574
                        c = fgetc_(file);
-
 
1575
                        if(c != EOF)
-
 
1576
                        {
1382
        {
1577
                                *pbuff = (uint8_t)c;                                                                    // read a byte from the buffer to the opened file.
-
 
1578
                                pbuff++;
Line -... Line 1579...
-
 
1579
                                size--;
-
 
1580
                        }
-
 
1581
                        else // error or end of file reached
-
 
1582
                        {
-
 
1583
                                success = 0;
1383
                item->name[i] = 0;
1584
                        }
-
 
1585
                }
-
 
1586
                if(success) object_cnt++;
-
 
1587
        }
-
 
1588
        return(object_cnt);                                                                                             // return the number of objects succesfully read from the file
-
 
1589
}
-
 
1590
 
-
 
1591
 
-
 
1592
/****************************************************************************************************************************************/
1384
        }
1593
/*      Function:               fwrite_(void *buffer, uint32_t size, uint32_t count, File *file);                                                                                                                               */
-
 
1594
/*                                                                                                                                                                                                                                                                              */
-
 
1595
/*      Description:    This function writes count objects of the specified size                                                                                                                        */
-
 
1596
/*                                      from the buffer pointer to the actual position in the file.                                                                                                                     */
-
 
1597
/*                                                                                                                                                                                                                                                                              */
-
 
1598
/*      Returnvalue:    The function returns the number of objects (not bytes) read from the file.                                                                                      */
-
 
1599
/****************************************************************************************************************************************/
-
 
1600
uint32_t fwrite_(void *buffer, uint32_t size, uint32_t count, File_t *file)
-
 
1601
{
Line -... Line 1602...
-
 
1602
        uint32_t object_cnt     = 0;                                                                                                            // count the number of objects written to the file.
-
 
1603
        uint32_t object_size = 0;                                                                                                               // count the number of bytes written from the actual object.
-
 
1604
        uint8_t *pbuff      = 0;                                                                                                                // a pointer to the actual bufferposition.
-
 
1605
        uint8_t success      = 1;                                                                                                               // no error occured during write operation to the file.
1385
 
1606
        int16_t c;
-
 
1607
 
-
 
1608
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
-
 
1609
 
-
 
1610
        pbuff = (uint8_t *) buffer;                                                                                                             // cast the void pointer to an u8 *
-
 
1611
 
-
 
1612
        while((object_cnt < count) && success)
-
 
1613
        {
-
 
1614
                object_size = size;
-
 
1615
                while((size > 0) && success)
-
 
1616
                {
-
 
1617
                        c = fputc_(*pbuff, file);                                                                               // write a byte from the buffer to the opened file.
-
 
1618
                        if(c != EOF)
-
 
1619
                        {
-
 
1620
                                pbuff++;
-
 
1621
                                size--;
-
 
1622
                        }
-
 
1623
                        else
-
 
1624
                        {
-
 
1625
                                success = 0;
-
 
1626
                        }
-
 
1627
                }
-
 
1628
                if(success) object_cnt++;
-
 
1629
        }
-
 
1630
 
-
 
1631
        return(object_cnt);                                                                                                                             // return the number of objects succesfully written to the file
-
 
1632
}
-
 
1633
 
-
 
1634
 
-
 
1635
/****************************************************************************************************************************************/
-
 
1636
/*      Function:               fputs_(const int8_t *string, File_t *File);                                                                                                                                                             */
-
 
1637
/*                                                                                                                                                                                                                                                                              */
-
 
1638
/*      Description:    This function writes a string to the specified file.                                                                                                                            */
1386
        retvalue = FindItem(item);
1639
/*                                                                                                                                                                                                                                                                              */
1387
 
-
 
1388
        return(retvalue);
-
 
1389
}
1640
/*      Returnvalue:    The function returns a no negative value or EOF on error.                                                                                                                       */
1390
 
-
 
1391
 
1641
/****************************************************************************************************************************************/
1392
 
-
 
1393
//________________________________________________________________________________________________________________________________________
1642
int16_t fputs_(const int8_t *string, File_t *file)
1394
// Funtion:     u8 fdelete(s8 *fname)
1643
{
-
 
1644
        uint8_t i=0;
-
 
1645
        int16_t c = 0;
-
 
1646
 
1395
//
1647
        if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(0);
1396
// Description: Deletes the file specified by fname.
-
 
1397
//
1648
 
Line 1398... Line -...
1398
// Returnvalue:
-
 
1399
//________________________________________________________________________________________________________________________________________
-
 
1400
 
-
 
1401
 
-