Subversion Repositories NaviCtrl

Rev

Rev 210 | Rev 218 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 210 Rev 211
Line 59... Line 59...
59
#include "timer1.h"
59
#include "timer1.h"
60
#include "fat16.h"
60
#include "fat16.h"
61
#include "sdc.h"
61
#include "sdc.h"
62
#include "uart1.h"
62
#include "uart1.h"
Line 63... Line -...
63
 
-
 
64
 
63
 
65
//________________________________________________________________________________________________________________________________________
64
//________________________________________________________________________________________________________________________________________
66
// Module name:                 fat16.c
65
// Module name:                 fat16.c
67
// Compiler used:               avr-gcc 3.4.5
66
// Compiler used:               avr-gcc 3.4.5
68
// Last Modifikation:   16.06.2008
67
// Last Modifikation:   20.03.2010
69
// Version:                             2.00
68
// Version:                             2.10
70
// Authors:                             Stephan Busker & Gregor Stobrawa
69
// Authors:                             Stephan Busker & Gregor Stobrawa
71
// Description:                 Source files for FAT16 implementation with read and write-access
70
// Description:                 Source files for FAT16 implementation with read and write-access
72
//                                              Copyright (C) 2008 Stephan Busker & Gregor Stobrawa
71
//                                              Copyright (C) 2008 Stephan Busker & Gregor Stobrawa
73
//........................................................................................................................................
72
//........................................................................................................................................
74
// Functions:                   extern s16              Fat16_Init(void);
73
// Functions:                   extern s16              Fat16_Init(void);
-
 
74
//                                              extern s16              Fat16_Deinit(void);
75
//                                              extern s16              Fat16_Deinit(void);
75
//                                              extern s8*              FAT16_GetVolumeLabel(void);
76
//                                              extern File_t * fopen_(const u8 *filename, const s8 mode);
76
//                                              extern File_t * fopen_(const u8 *filename, const s8 mode);
-
 
77
//                                              extern s16              fclose_(File_t *File);
77
//                                              extern s16              fclose_(File_t *File);
78
//                                              extern u8               fexist_(s8 * const filename);
78
//                                              extern s16              fflush_(File_t *File);
79
//                                              extern s16              fflush_(File_t *File);
79
//                                              extern s16      fseek_(File_t *File, s32 offset, s16 origin);
80
//                                              extern s16      fseek_(File_t *File, s32 offset, s16 origin);
80
//                                              extern s16              fgetc_(File_t *File);
81
//                                              extern s16              fgetc_(File_t *File);
81
//                                              extern s16              fputc_(u8 c, File_t *File);
82
//                                              extern s16              fputc_(u8 c, File_t *File);
82
//                                              extern u32              fread_(void *buffer, u32 size, u32 count, File_t *File);
83
//                                              extern u32              fread_(void *buffer, u32 size, u32 count, File_t *File);
83
//                                              extern u32              fwrite_(void *buffer, u32 size, u32 count, File_t *File);
84
//                                              extern u32              fwrite_(void *buffer, u32 size, u32 count, File_t *File);
84
//                                              extern s16              fputs_(const u8 *string, File_t *File);
85
//                                              extern s16              fputs_(const u8 *string, File_t *File);
-
 
86
//                                              extern u8 *     fgets_(u8 *string, s16 length, File_t *File);
85
//                                              extern u8 *     fgets_(u8 *string, s16 length, File_t *File);
87
//                                              extern u8               feof_(File_t * const file);
86
//........................................................................................................................................
88
//........................................................................................................................................
87
// ext. functions:              extern SD_Result_t SDC_Init(void;)
89
// ext. functions:              extern SD_Result_t SDC_Init(void;)
88
//                                              extern SD_Result_t SDC_Deinit(void);
90
//                                              extern SD_Result_t SDC_Deinit(void);
89
//                      extern SD_Result_t SDC_GetSector (u32,u8 *);
91
//                      extern SD_Result_t SDC_GetSector (u32,u8 *);
Line 228... Line 230...
228
typedef struct
230
typedef struct
229
{
231
{
230
        s8      Name[8];                                        // 8 bytes name, padded with spaces.
232
        s8      Name[8];                                        // 8 bytes name, padded with spaces.
231
        u8      Extension[3];                           // 3 bytes extension, padded with spaces.
233
        u8      Extension[3];                           // 3 bytes extension, padded with spaces.
232
        u8      Attribute;                                      // attribute of the directory entry (unused,archive,read-only,system,directory,volume)
234
        u8      Attribute;                                      // attribute of the directory entry (unused,archive,read-only,system,directory,volume)
-
 
235
        u8  Res1;                                               // should be zero
233
        u8      Reserved[10];                           // reserved bytes within the directory entry.
236
        u8  CreationTime10ms;                   // subsecond resolution of creation time
-
 
237
        u16 CreationTime;                               // Time of creation h:m:s
-
 
238
        u16 CreationDate;                               // Date of creation Y.M.D
-
 
239
        u16 LastAccessDate;             // The date where the file was last accessed
-
 
240
        u8      Res2[2];                                    // should be zero
-
 
241
        u16 ModTime;                                    // date of last write access
234
        u32 DateTime;                                   // date and time of last write access to the file or directory.
242
        u16 ModDate;                                    // date of last write access to the file or directory.
235
        u16 StartCluster;                               // first cluster of the file or directory.
243
        u16 StartCluster;                               // first cluster of the file or directory.
236
        u32 Size;                                               // size of the file or directory in bytes.
244
        u32 Size;                                               // size of the file or directory in bytes.
237
}  __attribute__((packed)) DirEntry_t;
245
}  __attribute__((packed)) DirEntry_t;
Line 238... Line 246...
238
 
246
 
Line 282... Line 290...
282
#define DIRENTRY_SIZE                           32              //bytes
290
#define DIRENTRY_SIZE                           32              //bytes
283
#define DIRENTRIES_PER_SECTOR           BYTES_PER_SECTOR/DIRENTRY_SIZE
291
#define DIRENTRIES_PER_SECTOR           BYTES_PER_SECTOR/DIRENTRY_SIZE
284
#define FAT16_BYTES                                     2
292
#define FAT16_BYTES                                     2
285
#define FAT16_ENTRIES_PER_SECTOR        BYTES_PER_SECTOR/FAT16_BYTES
293
#define FAT16_ENTRIES_PER_SECTOR        BYTES_PER_SECTOR/FAT16_BYTES
Line -... Line 294...
-
 
294
 
-
 
295
#define SECTOR_UNDEFINED        0x00000000L
-
 
296
#define CLUSTER_UNDEFINED       0x0000
286
 
297
 
287
#define FSTATE_UNUSED   0
298
#define FSTATE_UNUSED   0
Line 288... Line 299...
288
#define FSTATE_USED             1
299
#define FSTATE_USED             1
289
 
300
 
Line 305... Line 316...
305
 
316
 
Line 306... Line 317...
306
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
317
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
307
 
318
 
308
 
319
 
309
/****************************************************************************************************************************************/
320
/****************************************************************************************************************************************/
310
/*      Function:               FileDateTime(DateTime_t *);                                                                                                                                                                                     */
321
/*      Function:               FileDate(DateTime_t *);                                                                                                                                                                                         */
311
/*                                                                                                                                                                                                                                                                              */
322
/*                                                                                                                                                                                                                                                                              */
312
/*      Description:    This function calculates the DOS date time from a pointer to a time structure.                                                                          */
323
/*      Description:    This function calculates the DOS date from a pointer to a time structure.                                                                                       */
313
/*                                                                                                                                                                                                                                                                              */
-
 
314
/*      Returnvalue:    Returns the DOS date time.                                                                                                                                                                                      */
324
/*                                                                                                                                                                                                                                                                              */
315
/****************************************************************************************************************************************/
325
/*      Returnvalue:    Returns the DOS date.                                                                                                                                                                                           */
316
 
326
/****************************************************************************************************************************************/
-
 
327
u16 FileDate(DateTime_t * pTimeStruct)
317
u32 FileDateTime(DateTime_t * pTimeStruct)
328
{
Line 318... Line 329...
318
{
329
        u16 date = 0;
319
        u32 datetime = 0;
330
        if(pTimeStruct == NULL)   return date;
320
        if((pTimeStruct == 0) || !(pTimeStruct->Valid)) return datetime;
331
        if(!(pTimeStruct->Valid)) return date;
321
 
-
 
322
        datetime |= (0x0000007FL & (u32)(pTimeStruct->Year - 1980))<<25; // set year
-
 
323
        datetime |= (0x0000000FL & (u32)(pTimeStruct->Month))<<21; // set month
-
 
324
        datetime |= (0x0000001FL & (u32)(pTimeStruct->Day))<<16;
332
 
325
        datetime |= (0x0000001FL & (u32)(pTimeStruct->Hour))<<11;
333
        date |= (0x007F & (u16)(pTimeStruct->Year - 1980))<<9; // set year
Line -... Line 334...
-
 
334
        date |= (0x000F & (u16)(pTimeStruct->Month))<<5; // set month
-
 
335
        date |= (0x001F & (u16)(pTimeStruct->Day));
-
 
336
        return date;
-
 
337
}
-
 
338
 
-
 
339
/****************************************************************************************************************************************/
-
 
340
/*      Function:               FileTime(DateTime_t *);                                                                                                                                                                                         */
-
 
341
/*                                                                                                                                                                                                                                                                              */
-
 
342
/*      Description:    This function calculates the DOS time from a pointer to a time structure.                                                                                       */
-
 
343
/*                                                                                                                                                                                                                                                                              */
-
 
344
/*      Returnvalue:    Returns the DOS time.                                                                                                                                                                                           */
-
 
345
/****************************************************************************************************************************************/
-
 
346
 
-
 
347
u16 FileTime(DateTime_t * pTimeStruct)
-
 
348
{
-
 
349
        u16 time = 0;
-
 
350
        if(pTimeStruct == NULL)   return time;
-
 
351
        if(!(pTimeStruct->Valid)) return time;
-
 
352
 
Line 326... Line 353...
326
        datetime |= (0x0000003FL & (u32)(pTimeStruct->Min))<<5;
353
        time |= (0x001F & (u16)(pTimeStruct->Hour))<<11;
327
        datetime |= (0x0000001FL & (u32)(pTimeStruct->Sec/2));
354
        time |= (0x003F & (u16)(pTimeStruct->Min))<<5;
328
        return datetime;
355
        time |= (0x001F & (u16)(pTimeStruct->Sec/2));
329
}
356
        return time;
Line 366... Line 393...
366
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
393
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
367
        {
394
        {
368
                if(&FilePointer[cnt] == file)                                           // filepointer to be freed found?
395
                if(&FilePointer[cnt] == file)                                           // filepointer to be freed found?
369
                {
396
                {
370
                        file->State = FSTATE_UNUSED;
397
                        file->State = FSTATE_UNUSED;
371
                        file->FirstSectorOfFirstCluster = 0;                    // Sectorpointer to the first sector of the first datacluster of the file.
398
                        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;                     // Sectorpointer to the first sector of the first datacluster of the file.
372
                        file->FirstSectorOfCurrCluster  = 0;
-
 
373
                        file->SectorOfCurrCluster               = 0;                    // Pointer to the cluster which is edited at the moment.
399
                        file->FirstSectorOfCurrCluster  = SECTOR_UNDEFINED;                     // Pointer to the cluster which is edited at the moment.
374
                        file->SectorOfCurrCluster               = 0;                    // The sector which is edited at the moment (cluster_pointer + sector_index).
400
                        file->SectorOfCurrCluster               = 0;                    // The sector which is edited at the moment (cluster_pointer + sector_index).
375
                        file->ByteOfCurrSector                  = 0;                    // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
401
                        file->ByteOfCurrSector                  = 0;                    // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
376
                        file->Mode                                              = 0;                    // mode of fileoperation (read,write)
402
                        file->Mode                                              = 0;                    // mode of fileoperation (read,write)
377
                        file->Size                                              = 0;                    // the size of the opend file in bytes.
403
                        file->Size                                              = 0;                    // the size of the opend file in bytes.
378
                        file->Position                                  = 0;                    // pointer to a character within the file 0 < fileposition < filesize
404
                        file->Position                                  = 0;                    // pointer to a character within the file 0 < fileposition < filesize
379
                        file->SectorInCache                     = 0;                    // the last sector read, wich is still in the sectorbuffer.
405
                        file->SectorInCache                     = SECTOR_UNDEFINED;                     // the last sector read, wich is still in the sectorbuffer.
380
                        file->DirectorySector                   = 0;                    // the sectorposition where the directoryentry has been made.
406
                        file->DirectorySector                   = SECTOR_UNDEFINED;                     // the sectorposition where the directoryentry has been made.
381
                        file->DirectoryIndex                    = 0;                    // the index to the directoryentry within the specified sector.
407
                        file->DirectoryIndex                    = 0;                    // the index to the directoryentry within the specified sector.
382
                        file->Attribute                                 = 0;                    // the attribute of the file opened.
408
                        file->Attribute                                 = 0;                    // the attribute of the file opened.
383
                        file = NULL;
409
                        file = NULL;
384
                        return(1);
410
                        return(1);
385
                }
411
                }
Line 460... Line 486...
460
/*                                                                                                                                                                                                                                                                              */
486
/*                                                                                                                                                                                                                                                                              */
461
/*      Returnvalue: The sector number with the data area of the given cluster                                                                                                                          */
487
/*      Returnvalue: The sector number with the data area of the given cluster                                                                                                                          */
462
/****************************************************************************************************************************************/
488
/****************************************************************************************************************************************/
463
u32     Fat16ClusterToSector(u16 cluster)
489
u32     Fat16ClusterToSector(u16 cluster)
464
{
490
{
465
        if(!Partition.IsValid) return 0;
491
        if(!Partition.IsValid) return SECTOR_UNDEFINED;
466
        if (cluster < 2) cluster = 2; // the 0. and 1. cluster in the fat are used for the media descriptor
492
        if (cluster < 2)
-
 
493
        {
-
 
494
                return SECTOR_UNDEFINED;
-
 
495
        }
-
 
496
        else
-
 
497
        {
467
        return ( (cluster - 2) * Partition.SectorsPerCluster) + Partition.FirstDataSector; // the first data sector     is represented by the 2nd cluster
498
                return ( (cluster - 2) * Partition.SectorsPerCluster) + Partition.FirstDataSector; // the first data sector     is represented by the 2nd cluster
-
 
499
        }
468
}
500
}
Line 469... Line 501...
469
 
501
 
470
/****************************************************************************************************************************************/
502
/****************************************************************************************************************************************/
471
/*      Function:       SectorToFat16Cluster( u32 sector);                                                                                                                                                                              */
503
/*      Function:       SectorToFat16Cluster( u32 sector);                                                                                                                                                                              */
Line 475... Line 507...
475
/*                                                                                                                                                                                                                                                                              */
507
/*                                                                                                                                                                                                                                                                              */
476
/*      Returnvalue: The cluster number representing the data area of the sector.                                                                                                                       */
508
/*      Returnvalue: The cluster number representing the data area of the sector.                                                                                                                       */
477
/****************************************************************************************************************************************/
509
/****************************************************************************************************************************************/
478
u16     SectorToFat16Cluster(u32 sector)
510
u16     SectorToFat16Cluster(u32 sector)
479
{
511
{
480
        if(!Partition.IsValid) return 0;
512
        if(!Partition.IsValid) return CLUSTER_UNDEFINED;
-
 
513
        if((sector == SECTOR_UNDEFINED) || (sector < Partition.FirstDataSector)) return CLUSTER_UNDEFINED;
481
        return ((u16)((sector - Partition.FirstDataSector) / Partition.SectorsPerCluster) + 2);
514
        else return ((u16)((sector - Partition.FirstDataSector) / Partition.SectorsPerCluster) + 2);
482
}
515
}
Line 483... Line 516...
483
 
516
 
484
 
517
 
Line 512... Line 545...
512
        {
545
        {
513
                if(FilePointer[cnt].State == FSTATE_USED)
546
                if(FilePointer[cnt].State == FSTATE_USED)
514
                {
547
                {
515
                        returnvalue += fclose_(&FilePointer[cnt]); // try to close open file pointers
548
                        returnvalue += fclose_(&FilePointer[cnt]); // try to close open file pointers
516
                }
549
                }
-
 
550
                else UnlockFilePointer(&FilePointer[cnt]);
Line 517... Line 551...
517
 
551
 
518
        }
552
        }
519
        SDC_Deinit();                   // uninitialize interface to sd-card
553
        SDC_Deinit();                   // uninitialize interface to sd-card
520
        Partition.IsValid = 0;  // mark data in partition structure as invalid
554
        Partition.IsValid = 0;  // mark data in partition structure as invalid
Line 544... Line 578...
544
        Partition.IsValid = 0;
578
        Partition.IsValid = 0;
Line 545... Line 579...
545
 
579
 
546
        // declare the filepointers as unused.
580
        // declare the filepointers as unused.
547
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
581
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
548
        {
582
        {
549
                FilePointer[cnt].State = FSTATE_UNUSED;
583
                UnlockFilePointer(&FilePointer[cnt]);
550
        }
584
        }
551
        // set current file pinter to first position in list
585
        // set current file pinter to first position in list
Line 552... Line 586...
552
        file = &FilePointer[0];
586
        file = &FilePointer[0];
553
 
587
 
554
        // try to initialise the sd-card.
588
        // try to initialize the sd-card.
555
        if(SD_SUCCESS != SDC_Init())
589
        if(SD_SUCCESS != SDC_Init())
556
        {
590
        {
557
                UART1_PutString("SD-Card could not be initialized.");
591
                UART1_PutString("SD-Card could not be initialized.");
Line 647... Line 681...
647
        u32 i;
681
        u32 i;
Line 648... Line 682...
648
 
682
 
Line 649... Line 683...
649
        if((!Partition.IsValid) || (file == NULL)) return(0);
683
        if((!Partition.IsValid) || (file == NULL)) return(0);
-
 
684
 
650
 
685
        for(i = 0; i < BYTES_PER_SECTOR; i++) file->Cache[i] = 0; // clear file cache
651
        for(i = 0; i < BYTES_PER_SECTOR; i++) file->Cache[i] = 0; // clear file cache
686
        if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return (0); // nothing to do 
652
        for(i = 0; i < Partition.SectorsPerCluster; i++)
687
        for(i = 0; i < Partition.SectorsPerCluster; i++)
653
        {
688
        {
654
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
689
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
Line 668... Line 703...
668
/*                                                                                                                                                                                                                                                                               */
703
/*                                                                                                                                                                                                                                                                               */
669
/* Returnvalue: The function returns the next cluster or 0 if the last cluster has already reached.                                                                                                      */
704
/* Returnvalue: The function returns the next cluster or 0 if the last cluster has already reached.                                                                                                      */
670
/*****************************************************************************************************************************************/
705
/*****************************************************************************************************************************************/
671
u16 GetNextCluster(File_t * file)
706
u16 GetNextCluster(File_t * file)
672
{
707
{
673
        u16 cluster = 0;
708
        u16 cluster = CLUSTER_UNDEFINED;
674
        u32 fat_byte_offset, sector, byte;
709
        u32 fat_byte_offset, sector, byte;
675
        Fat16Entry_t * fat;
710
        Fat16Entry_t * fat;
Line 676... Line 711...
676
 
711
 
-
 
712
        if((!Partition.IsValid) || (file == NULL)) return(cluster);
677
        if((!Partition.IsValid) || (file == NULL)) return(cluster);
713
        if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(cluster);
678
        // if sector is within the data area
714
        // if sector is within the data area
679
        if((Partition.FirstDataSector <= file->FirstSectorOfCurrCluster)&& (file->FirstSectorOfCurrCluster <= Partition.LastDataSector))
715
        if((Partition.FirstDataSector <= file->FirstSectorOfCurrCluster)&& (file->FirstSectorOfCurrCluster <= Partition.LastDataSector))
680
        {
716
        {
681
                // determine current file cluster
717
                // determine current file cluster
Line 697... Line 733...
697
                        }
733
                        }
698
                }
734
                }
699
                // read the next cluster from cache
735
                // read the next cluster from cache
700
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
736
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
701
                cluster = fat->NextCluster;
737
                cluster = fat->NextCluster;
702
                // if last cluster fat entry
738
                // if no next cluster exist
703
                if(FAT16_CLUSTER_LAST_MIN <= cluster)
739
                if(FAT16_CLUSTER_LAST_MIN <= cluster)
704
                {
740
                {
705
                         cluster = 0;
741
                         cluster = CLUSTER_UNDEFINED; // next cluster is undefined
706
                }
742
                }
707
                else
743
                else
708
                {
744
                {
709
                        file->FirstSectorOfCurrCluster = Fat16ClusterToSector(cluster);
745
                        file->FirstSectorOfCurrCluster = Fat16ClusterToSector(cluster);
710
                        file->SectorOfCurrCluster = 0;
746
                        file->SectorOfCurrCluster = 0;
Line 725... Line 761...
725
u16 FindNextFreeCluster(File_t *file)
761
u16 FindNextFreeCluster(File_t *file)
726
{
762
{
727
        u32 fat_sector;                                 // current sector within the fat relative to the first sector of the fat.
763
        u32 fat_sector;                                 // current sector within the fat relative to the first sector of the fat.
728
        u32     curr_sector;                            // current sector
764
        u32     curr_sector;                            // current sector
729
        u16     fat_entry;                                      // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
765
        u16     fat_entry;                                      // index to an fatentry within the actual sector (256 fatentries are possible within one sector).
730
        u16     free_cluster    = 0;            // next free cluster number.
766
        u16     free_cluster    = CLUSTER_UNDEFINED;    // next free cluster number.
731
        Fat16Entry_t * fat;
767
        Fat16Entry_t * fat;
Line 732... Line 768...
732
 
768
 
Line 733... Line 769...
733
        if((!Partition.IsValid) || (file == NULL)) return(0);
769
        if((!Partition.IsValid) || (file == NULL)) return(0);
Line 770... Line 806...
770
/****************************************************************************************************************************************************/
806
/****************************************************************************************************************************************************/
771
/* Function:    s16 fseek_(File_t *, s32 *, u8)                                                                                                                                                                                                         */
807
/* Function:    s16 fseek_(File_t *, s32 *, u8)                                                                                                                                                                                                         */
772
/*                                                                                                                                                                                                                                                                                                      */
808
/*                                                                                                                                                                                                                                                                                                      */
773
/* Description: This function sets the pointer of the stream relative to the position                                                                                                                           */
809
/* Description: This function sets the pointer of the stream relative to the position                                                                                                                           */
774
/*                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END)                                                                                                                                                                      */
810
/*                              specified by origin (SEEK_SET, SEEK_CUR, SEEK_END)                                                                                                                                                                      */
775
/* Returnvalue: Is 1 if seek was successful                                                                                                                                                                                                                                                                     */
811
/* Returnvalue: Is 0 if seek was successful                                                                                                                                                                                                                                                                     */
776
/****************************************************************************************************************************************************/
812
/****************************************************************************************************************************************************/
777
s16 fseek_(File_t *file, s32 offset, s16 origin)
813
s16 fseek_(File_t *file, s32 offset, s16 origin)
778
{
814
{
779
        s32             fposition       = 0;
815
        s32             fposition       = 0;
780
        s16     retvalue        = 1;
816
        s16     retvalue        = 1;
Line 781... Line 817...
781
 
817
 
782
        if((!Partition.IsValid) || (file == NULL)) return(0);
818
        if((!Partition.IsValid) || (file == NULL)) return(retvalue);
783
        switch(origin)
819
        switch(origin)
784
        {
820
        {
785
                case SEEK_SET:                          // Fileposition relative to the beginning of the file.
821
                case SEEK_SET:                          // Fileposition relative to the beginning of the file.
786
                        fposition = 0;
822
                        fposition = 0;
Line 801... Line 837...
801
                // reset file position to start of the file
837
                // reset file position to start of the file
802
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
838
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
803
                file->SectorOfCurrCluster       = 0;
839
                file->SectorOfCurrCluster       = 0;
804
                file->ByteOfCurrSector          = 0;
840
                file->ByteOfCurrSector          = 0;
805
                file->Position                          = 0;
841
                file->Position                          = 0;
806
 
-
 
-
 
842
                if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
807
                while(file->Position < fposition)       // repeat until the current position is less than target
843
                while(file->Position < fposition)       // repeat until the current position is less than target
808
                {
844
                {
809
                        file->Position++;                               // increment file position
845
                        file->Position++;                               // increment file position
810
                        file->ByteOfCurrSector++;               // next byte in current sector
846
                        file->ByteOfCurrSector++;               // next byte in current sector
811
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
847
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
Line 818... Line 854...
818
                                        {
854
                                        {
819
                                                file->SectorOfCurrCluster = 0;
855
                                                file->SectorOfCurrCluster = 0;
820
                                        }
856
                                        }
821
                                        else // the last cluster was allready reached
857
                                        else // the last cluster was allready reached
822
                                        {
858
                                        {
823
                                                file->SectorOfCurrCluster--;                                                    // jump back to the ast sector in the last cluster
859
                                                file->SectorOfCurrCluster--;                                                    // jump back to the last sector in the last cluster
824
                                                file->ByteOfCurrSector = BYTES_PER_SECTOR;                              // set ByteOfCurrSector one byte over sector end
860
                                                file->ByteOfCurrSector = BYTES_PER_SECTOR;                              // set ByteOfCurrSector one byte over sector end
825
                                        }
861
                                        }
826
                                }
862
                                }
827
                        }
863
                        }
828
                }
864
                }
Line 845... Line 881...
845
        Fat16Entry_t * fat;
881
        Fat16Entry_t * fat;
846
        u8 buffer[BYTES_PER_SECTOR];
882
        u8 buffer[BYTES_PER_SECTOR];
847
        u32 sector_in_buffer = 0;
883
        u32 sector_in_buffer = 0;
848
        u8 repeat = 0;
884
        u8 repeat = 0;
Line 849... Line 885...
849
 
885
 
-
 
886
        if(!Partition.IsValid) return(0);
850
        if(!Partition.IsValid) return 0;
887
        if(StartCluster == CLUSTER_UNDEFINED) return(0);
851
        cluster = StartCluster; // init chain trace
888
        cluster = StartCluster; // init chain trace
852
        // if start cluster is equal to the last cluster we are done
889
        // if start cluster is no real cluster
Line 853... Line 890...
853
        if(FAT16_CLUSTER_LAST_MIN <= cluster) return 1;
890
    if(FAT16_CLUSTER_LAST_MIN <= cluster) return 1;
854
 
891
 
855
        // calculate byte offset in the fat for corresponding entry
892
        // calculate byte offset in the fat for corresponding entry
856
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
893
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
Line 867... Line 904...
867
                        if(SD_SUCCESS != SDC_GetSector(sector_in_buffer, buffer)) return 0;     // read sector from sd-card
904
                        if(SD_SUCCESS != SDC_GetSector(sector_in_buffer, buffer)) return 0;     // read sector from sd-card
868
                }
905
                }
869
                // read the next cluster from cache
906
                // read the next cluster from cache
870
                fat = (Fat16Entry_t *)(&(buffer[byte]));
907
                fat = (Fat16Entry_t *)(&(buffer[byte]));
871
                cluster = fat->NextCluster;
908
                cluster = fat->NextCluster;
-
 
909
                fat->NextCluster =      FAT16_CLUSTER_FREE; // mark current cluster as free
-
 
910
 
872
                if((FAT16_CLUSTER_USED_MIN <= cluster) && (cluster <= FAT16_CLUSTER_USED_MAX) ) repeat = 1;
911
                if((FAT16_CLUSTER_USED_MIN <= cluster) && (cluster <= FAT16_CLUSTER_USED_MAX) )
-
 
912
                {
-
 
913
                        repeat = 1;
-
 
914
                        // calculate sector byte and byte offset in the fat for the next cluster
-
 
915
                        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
-
 
916
                        // calculate the sector that contains the current cluster within the fat
-
 
917
                        sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
918
                        // calculate byte offset of the current cluster within that fat sector
-
 
919
                        byte = fat_byte_offset % BYTES_PER_SECTOR;
-
 
920
                }
873
                else repeat = 0;
921
                else repeat = 0;
Line 874... Line -...
874
 
-
 
875
                fat->NextCluster =      FAT16_CLUSTER_FREE; // mark current cluster as free
-
 
876
                // calculate byte offset in the fat for corresponding entry
-
 
877
                fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
-
 
878
                // calculate the sector that contains the current cluster within the fat
-
 
879
                sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
880
                // calculate byte offset of the current cluster within that fat sector
-
 
881
                byte = fat_byte_offset % BYTES_PER_SECTOR;
922
 
882
                // if new sector is not the sector in buffer or the last cluster in the chain was traced
923
                // if new sector is not the sector in buffer or the last cluster in the chain was traced
883
                if((sector != sector_in_buffer) || !repeat)
924
                if((sector != sector_in_buffer) || !repeat)
884
                {       // write sector in buffer
925
                {       // write sector in buffer
885
                        if(SD_SUCCESS != SDC_PutSector(sector_in_buffer,buffer))
926
                        if(SD_SUCCESS != SDC_PutSector(sector_in_buffer,buffer))
886
                        {
927
                        {
887
                                Fat16_Deinit();
928
                                Fat16_Deinit();
888
                                return 0;
929
                                return(0);
889
                        }
930
                        }
890
                }
931
                }
891
        }
932
        }
Line 898... Line 939...
898
/****************************************************************************************************************************************/
939
/****************************************************************************************************************************************/
899
/* Function:    u16 AppendCluster(File *file);                                                                                                                                                                                  */
940
/* Function:    u16 AppendCluster(File *file);                                                                                                                                                                                  */
900
/*                                                                                                                                                                                                                                                                              */
941
/*                                                                                                                                                                                                                                                                              */
901
/* Description: This function looks in the fat to find the next free cluster and appends it to the file.                                                                */
942
/* Description: This function looks in the fat to find the next free cluster and appends it to the file.                                                                */
902
/*                                                                                                                                                                                                                                                                              */
943
/*                                                                                                                                                                                                                                                                              */
903
/* Returnvalue: The function returns the appened cluster number or 0 of no cluster was appended.                                                                                                                                                */
944
/* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended.                                                */
904
/****************************************************************************************************************************************/
945
/****************************************************************************************************************************************/
905
u16 AppendCluster(File_t *file)
946
u16 AppendCluster(File_t *file)
906
{
947
{
907
        u16 last_cluster, new_cluster = 0;
948
        u16 last_cluster, new_cluster = CLUSTER_UNDEFINED;
908
        u32 fat_byte_offset, sector, byte;
949
        u32 fat_byte_offset, sector, byte;
909
        Fat16Entry_t * fat;
950
        Fat16Entry_t * fat;
Line 910... Line 951...
910
 
951
 
Line 911... Line 952...
911
        if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
952
        if((!Partition.IsValid) || (file == NULL)) return(new_cluster);
912
 
953
 
913
        new_cluster = FindNextFreeCluster(file);        // the next free cluster found on the disk.
954
        new_cluster = FindNextFreeCluster(file);        // the next free cluster found on the disk.
914
        if(new_cluster)
955
        if(new_cluster != CLUSTER_UNDEFINED)
915
        {       // A free cluster was found and can be added to the end of the file.
956
        {       // A free cluster was found and can be added to the end of the file.
916
                fseek_(file, 0, SEEK_END);                                                                                                      // jump to the end of the file
-
 
917
                last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);            // determine current file cluster
-
 
918
                fat_byte_offset = ((u32)last_cluster)<<1;
-
 
919
                sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
920
                byte = fat_byte_offset % BYTES_PER_SECTOR;
957
                fseek_(file, 0, SEEK_END);                                                                                                      // jump to the end of the file
921
 
958
                last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster);            // determine current file cluster
-
 
959
                if(last_cluster != CLUSTER_UNDEFINED)
-
 
960
                {
-
 
961
                        // update FAT entry of last cluster
-
 
962
                        fat_byte_offset = ((u32)last_cluster)<<1;
-
 
963
                        sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
-
 
964
                        byte = fat_byte_offset % BYTES_PER_SECTOR;
-
 
965
                        // read the sector containing the last cluster of the file
922
                if(file->SectorInCache != sector)
966
                        if(file->SectorInCache != sector)
923
                {
967
                        {
-
 
968
                                file->SectorInCache = sector;   // update sector stored in buffer
-
 
969
                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
-
 
970
                                {
-
 
971
                                        Fat16_Deinit();
-
 
972
                                        return(0);
-
 
973
                                }
-
 
974
                        }
-
 
975
                        fat = (Fat16Entry_t *)(&(file->Cache[byte]));
924
                        file->SectorInCache = sector;                                           // update sector stored in buffer
976
                        fat->NextCluster = new_cluster;                                                 // append the free cluster to the end of the file in the FAT.
925
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
977
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // save the modified sector to the FAT.
926
                        {
978
                        {
927
                                Fat16_Deinit();
979
                                Fat16_Deinit();
928
                                return(0);
980
                                return(0);
929
                        }
981
                        }
-
 
982
                }
-
 
983
                else // last cluster of the file is undefined
-
 
984
                {   // then the new cluster must be the first one of the file
930
                }
985
                    // and its cluster number must be set in the direntry
931
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
986
                        DirEntry_t * dir;
932
                fat->NextCluster = new_cluster;                                                 // append the free cluster to the end of the file in the FAT.
987
                        file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
933
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // save the modified sector to the FAT.
988
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
989
                        {
-
 
990
                                Fat16_Deinit();
-
 
991
                                return(CLUSTER_UNDEFINED);
-
 
992
                        }
-
 
993
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
994
                        dir[file->DirectoryIndex].Res1 = 0;
-
 
995
                        dir[file->DirectoryIndex].Res2[0] = 0;
-
 
996
                        dir[file->DirectoryIndex].Res2[1] = 0;
-
 
997
                        dir[file->DirectoryIndex].StartCluster = new_cluster;           // update startcluster 
-
 
998
                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);// set time
-
 
999
                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);// and date of modification
-
 
1000
                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
-
 
1001
                        dir[file->DirectoryIndex].Size          = 0;
-
 
1002
                        // write sector containing the direntry
934
                {
1003
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
-
 
1004
                        {
-
 
1005
                                Fat16_Deinit();
-
 
1006
                                return(CLUSTER_UNDEFINED);
-
 
1007
                        }
-
 
1008
                        // update file info     
-
 
1009
                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster);
935
                        Fat16_Deinit();
1010
                        file->Size = 0;
-
 
1011
                        file->Position = 0;
936
                        return(0);
1012
                }
937
                }
1013
                // update file pointes
938
                file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster);
1014
                file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster);
939
                file->SectorOfCurrCluster = 0;
1015
                file->SectorOfCurrCluster = 0;
940
                file->ByteOfCurrSector = 0;
1016
                file->ByteOfCurrSector = 0;
Line 964... Line 1040...
964
 
1040
 
965
        // dir entries can be searched only in filesclusters that have
1041
        // dir entries can be searched only in filesclusters that have
966
        // a corresponding dir entry with adir-flag set in its attribute
1042
        // a corresponding dir entry with adir-flag set in its attribute
Line 967... Line 1043...
967
        // or direct within the root directory area
1043
        // or direct within the root directory area
968
 
1044
 
969
        file->FirstSectorOfFirstCluster = 0;
1045
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
970
        // no current directory exist therefore assume searching in the root
1046
        // no current directory exist therefore assume searching in the root
971
        if(file->DirectorySector == 0)
1047
        if(file->DirectorySector == SECTOR_UNDEFINED)
972
        {
1048
        {
973
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
1049
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
974
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
1050
                file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
Line 983... Line 1059...
983
        {
1059
        {
984
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
1060
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
985
        }
1061
        }
986
        else return (direntry_exist); // bad sector range for directory sector of the file
1062
        else return (direntry_exist); // bad sector range for directory sector of the file
987
        // if search area is not defined yet
1063
        // if search area is not defined yet
988
        if(file->FirstSectorOfFirstCluster == 0)
1064
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
989
        {
1065
        {
990
                // check if the directory entry of current file is existent and has the dir-flag set
1066
                // check if the directory entry of current file is existent and has the dir-flag set
991
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1067
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
992
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1068
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
993
                {
1069
                {
994
                        Fat16_Deinit();
1070
                        Fat16_Deinit();
995
                        return(direntry_exist);
1071
                        return(direntry_exist);
996
                }
1072
                }
997
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1073
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
998
                switch((u8)dir[file->DirectoryIndex].Name[0])                                   // check if current directory exist
1074
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
999
                {
1075
                {
1000
                        case SLOT_EMPTY:
1076
                        case SLOT_EMPTY:
1001
                        case SLOT_DELETED:
1077
                        case SLOT_DELETED:
1002
                                // the directrory pointer of this file points to a deleted or not existen directory
1078
                                // the directrory pointer of this file points to a deleted or not existen directory
1003
                                // therefore no file or subdirectory can be created
1079
                                // therefore no file or subdirectory can be created
Line 1096... Line 1172...
1096
        // It is not checked here that the dir entry that should be created is already existent!
1172
        // It is not checked here that the dir entry that should be created is already existent!
Line 1097... Line 1173...
1097
 
1173
 
1098
        // Dir entries can be created only in file-clusters that have
1174
        // Dir entries can be created only in file-clusters that have
Line 1099... Line 1175...
1099
        // the dir-flag set in its attribute or within the root directory
1175
        // the dir-flag set in its attribute or within the root directory
1100
 
1176
 
1101
        file->FirstSectorOfFirstCluster = 0;
1177
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1102
        // no current directory exist therefore assume creating in the root
1178
        // no current directory exist therefore assume creating in the root
1103
        if(file->DirectorySector == 0)
1179
        if(file->DirectorySector == SECTOR_UNDEFINED)
1104
        {
1180
        {
1105
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
1181
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
1106
                dircluster = 0;
1182
                dircluster = 0;
Line 1116... Line 1192...
1116
        {
1192
        {
1117
                max_dir_sector = Partition.SectorsPerCluster;
1193
                max_dir_sector = Partition.SectorsPerCluster;
1118
        }
1194
        }
1119
        else return (retvalue); // bad sector range for directory sector of the file
1195
        else return (retvalue); // bad sector range for directory sector of the file
1120
        // if search area is not defined yet
1196
        // if search area is not defined yet
1121
        if(file->FirstSectorOfFirstCluster == 0)
1197
        if(file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED)
1122
        {
1198
        {
1123
            // check if the directory entry of current file is existent and has the dir-flag set
1199
            // check if the directory entry of current file is existent and has the dir-flag set
1124
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1200
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1125
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1201
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1126
                {
1202
                {
Line 1143... Line 1219...
1143
                }
1219
                }
1144
                dircluster = dir[file->DirectoryIndex].StartCluster;
1220
                dircluster = dir[file->DirectoryIndex].StartCluster;
1145
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dircluster);
1221
                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dircluster);
1146
        }
1222
        }
Line 1147... Line 1223...
1147
 
1223
 
1148
        subdircluster = FindNextFreeCluster(file);      // get the next free cluster on the disk and mark it as used.
1224
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
-
 
1225
        file->SectorOfCurrCluster               = 0;
1149
        if(subdircluster)
1226
        do // loop over all clusters of current directory
1150
        {
-
 
1151
                file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
-
 
1152
                file->SectorOfCurrCluster               = 0;
-
 
1153
                do // loop over all clusters of current directory
-
 
1154
                {
1227
        {
1155
                        dir_sector = 0; // reset sector counter within a new cluster
1228
                dir_sector = 0; // reset sector counter within a new cluster
1156
                        do // loop over all sectors of a cluster or all sectors of the root directory
1229
                do // loop over all sectors of a cluster or all sectors of the root directory
1157
                        {
1230
                {
1158
                                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1231
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1159
                                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1232
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1160
                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1233
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1161
                                {
1234
                        {
1162
                                        Fat16_Deinit();
1235
                                Fat16_Deinit();
1163
                                        return(retvalue);
1236
                                return(retvalue);
-
 
1237
                        }
1164
                                }
1238
 
1165
                                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1239
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1166
                                // search all directory entries of a sector
1240
                        // search all directory entries of a sector
1167
                                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
1241
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
1168
                                {       // check if current direntry is available
1242
                        {       // check if current direntry is available
1169
                                        if(((u8)dir[dir_entry].Name[0] == SLOT_EMPTY) || ((u8)dir[dir_entry].Name[0] == SLOT_DELETED))
1243
                                if(((u8)dir[dir_entry].Name[0] == SLOT_EMPTY) || ((u8)dir[dir_entry].Name[0] == SLOT_DELETED))
1170
                                        {       // a free direntry was found
1244
                                {       // a free direntry was found
-
 
1245
                                        for(i = 0; i < 11; i++) dir[dir_entry].Name[i] = dirname[i];            // Set dir name
-
 
1246
                                        dir[dir_entry].Attribute    = attrib;
-
 
1247
                                        dir[dir_entry].Res1 = 0;
-
 
1248
                                        dir[dir_entry].CreationTime10ms = (u8)(SystemTime.mSec/10);
-
 
1249
                                        dir[dir_entry].CreationTime     = FileTime(&SystemTime);
-
 
1250
                                        dir[dir_entry].CreationDate     = FileDate(&SystemTime);
-
 
1251
                                        dir[dir_entry].LastAccessDate = dir[dir_entry].CreationDate;
-
 
1252
                                        dir[dir_entry].Res2[0] = 0;
-
 
1253
                                        dir[dir_entry].Res2[1] = 0;
-
 
1254
                                        dir[dir_entry].ModTime = dir[dir_entry].CreationTime;
-
 
1255
                                        dir[dir_entry].ModDate = dir[dir_entry].CreationDate;
-
 
1256
                                        // if the new direntry is a subdirectory
-
 
1257
                                        if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)
-
 
1258
                                        {       // get a free clutser for its content
-
 
1259
                                                subdircluster = FindNextFreeCluster(file);      // get the next free cluster on the disk and mark it as used.
-
 
1260
                                                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
-
 
1261
                                        }
-
 
1262
                                        else // normal file
-
 
1263
                                        {       // has no data cluster after creation
-
 
1264
                                                subdircluster = CLUSTER_UNDEFINED;
-
 
1265
                                                file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1171
                                                for(i = 0; i < 11; i++) dir[dir_entry].Name[i] = dirname[i];            // Set dir name
1266
                                        }
1172
                                                dir[dir_entry].Attribute    = attrib;                                                           // Set the attribute of the new directoryentry.
1267
                                        // Set the attribute of the new directoryentry.
1173
                                                dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
1268
                                        dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
-
 
1269
                                        dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
-
 
1270
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
-
 
1271
                                        {
-
 
1272
                                                Fat16_Deinit();
-
 
1273
                                                return(retvalue);
-
 
1274
                                        }
-
 
1275
                                        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1174
                                                dir[dir_entry].DateTime         = FileDateTime(&SystemTime);                    // set date/time
1276
                                        file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
-
 
1277
                                        file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
-
 
1278
                                        file->Attribute                                 = attrib;                                               // set file attribute to dir attribute
-
 
1279
                                        file->Size                                              = 0;                                                        // new file has no size
-
 
1280
                                        file->DirectorySector                   = curr_sector;
-
 
1281
                                        file->DirectoryIndex                    = dir_entry;
-
 
1282
                                        // prepare subdirectory data cluster
-
 
1283
                                        if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)                           // if a new directory was created then initilize the data area
-
 
1284
                                        {
-
 
1285
                                                ClearCurrCluster(file); // fill cluster with zeros
1175
                                                dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
1286
                                                file->SectorInCache = file->FirstSectorOfFirstCluster;
1176
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
1287
                                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1177
                                                {
1288
                                                {
1178
                                                        Fat16_Deinit();
1289
                                                        Fat16_Deinit();
1179
                                                        return(retvalue);
1290
                                                        return(retvalue);
-
 
1291
                                                }
1180
                                                }
1292
                                                dir = (DirEntry_t *)file->Cache;
-
 
1293
                                                // create direntry "." to current dir
1181
                                                file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
1294
                                                dir[0].Name[0] = 0x2E;
-
 
1295
                                                for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
1182
                                                file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1296
                                                dir[0].Attribute = ATTR_SUBDIRECTORY;
-
 
1297
                                                dir[0].StartCluster = subdircluster;
1183
                                                file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
1298
                                                dir[0].Size = 0;
-
 
1299
                                                // create direntry ".." to the upper dir
-
 
1300
                                                dir[1].Name[0] = 0x2E;
1184
                                                file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
1301
                                                dir[1].Name[1] = 0x2E;
1185
                                                file->Attribute                                 = attrib;                                               // set file attribute to dir attribute
1302
                                                for(i = 2; i < 11; i++) dir[1].Name[i] = ' ';
1186
                                                file->Size                                              = 0;                                                        // new file has no size
1303
                                                dir[1].Attribute = ATTR_SUBDIRECTORY;
1187
                                                file->DirectorySector                   = curr_sector;
1304
                                                dir[1].StartCluster = dircluster;
1188
                                                file->DirectoryIndex                    = dir_entry;
1305
                                                dir[1].Size = 0;
1189
                                                if((attrib & ATTR_SUBDIRECTORY) == ATTR_SUBDIRECTORY)                           // if a new directory was created then initilize the data area
1306
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
1190
                                                {
-
 
1191
                                                        ClearCurrCluster(file); // fill cluster with zeros
-
 
1192
                                                        file->SectorInCache = file->FirstSectorOfFirstCluster;
-
 
1193
                                                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
1194
                                                        {
1307
                                                {
1195
                                                                Fat16_Deinit();
-
 
1196
                                                                return(retvalue);
-
 
1197
                                                        }
-
 
1198
                                                        dir = (DirEntry_t *)file->Cache;
-
 
1199
                                                        // create direntry "." to current dir
-
 
1200
                                                        dir[0].Name[0] = 0x2E;
-
 
1201
                                                        for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
-
 
1202
                                                        dir[0].Attribute = ATTR_SUBDIRECTORY;
-
 
1203
                                                        dir[0].StartCluster = subdircluster;
-
 
1204
                                                        dir[0].DateTime = 0;
-
 
1205
                                                        dir[0].Size = 0;
-
 
1206
                                                        // create direntry ".." to the upper dir
-
 
1207
                                                        dir[1].Name[0] = 0x2E;
-
 
1208
                                                        dir[1].Name[1] = 0x2E;
-
 
1209
                                                        for(i = 2; i < 11; i++) dir[1].Name[i] = ' ';
-
 
1210
                                                        dir[1].Attribute = ATTR_SUBDIRECTORY;
-
 
1211
                                                        dir[1].StartCluster = dircluster;
-
 
1212
                                                        dir[1].DateTime = 0;
-
 
1213
                                                        dir[1].Size = 0;
-
 
1214
                                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
1215
                                                        {
-
 
1216
                                                                Fat16_Deinit();
1308
                                                        Fat16_Deinit();
1217
                                                                return(retvalue);
1309
                                                        return(retvalue);
1218
                                                        }
1310
                                                }
1219
                                                }
1311
                                        }
1220
                                                retvalue = 1;
1312
                                        retvalue = 1;
1221
                                                dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
-
 
1222
                                        }
1313
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
-
 
1314
                                }
1223
                                }
1315
                        }
1224
                                dir_sector++; // search next sector
1316
                        dir_sector++; // search next sector
1225
                        // stop if we reached the end of the cluster or the end of the root dir
1317
                // stop if we reached the end of the cluster or the end of the root dir
1226
                        }while((dir_sector < max_dir_sector) && (!retvalue));
1318
                }while((dir_sector < max_dir_sector) && (!retvalue));
1227
 
1319
 
1228
                        // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1320
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1229
                        if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1321
                if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1230
                        {
1322
                {
1231
                                end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1323
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1232
                        }
1324
                }
1233
                }while((end_of_directory_not_reached) && (!retvalue));
1325
        }while((end_of_directory_not_reached) && (!retvalue));
1234
                // Perhaps we are at the end of the last cluster of a directory file an have no free direntry found.
1326
        // Perhaps we are at the end of the last cluster of a directory file and have no free direntry found.
1235
                // Then we would need to add a cluster to that file and create the new direntry there.
1327
        // Then we would need to add a cluster to that file and create the new direntry there.
1236
                // This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
1328
        // This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
1237
                // within a subdirectory of root.
1329
        // within a subdirectory of root.
1238
        }
1330
 
1239
        return(retvalue);       // return 1 if file has been created otherwise return 0.
1331
        return(retvalue);       // return 1 if file has been created otherwise return 0.
Line 1240... Line 1332...
1240
}
1332
}
1241
 
1333
 
Line 1380... Line 1472...
1380
        // if no unused file pointer was found return 0
1472
        // if no unused file pointer was found return 0
1381
        if(file == NULL) return(file);
1473
        if(file == NULL) return(file);
Line 1382... Line 1474...
1382
 
1474
 
1383
        // now we have found a free filepointer and claimed it
1475
        // now we have found a free filepointer and claimed it
1384
        // so let initiate its property values
1476
        // so let initiate its property values
1385
        file->FirstSectorOfFirstCluster = 0;            // Sectorpointer to the first sector of the first datacluster of the file.
1477
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;             // Sectorpointer to the first sector of the first datacluster of the file.
1386
        file->FirstSectorOfCurrCluster  = 0;            // Pointer to the cluster which is edited at the moment.
1478
        file->FirstSectorOfCurrCluster  = SECTOR_UNDEFINED;             // Pointer to the cluster which is edited at the moment.
1387
        file->SectorOfCurrCluster               = 0;            // The sector which is edited at the moment (cluster_pointer + sector_index).
1479
        file->SectorOfCurrCluster               = 0;            // The sector which is edited at the moment (cluster_pointer + sector_index).
1388
        file->ByteOfCurrSector                  = 0;            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
1480
        file->ByteOfCurrSector                  = 0;            // The bytelocation within the current sector (cluster_pointer + sector_index + byte_index).
1389
        file->Mode                                              = mode;         // mode of fileoperation (read,write)
1481
        file->Mode                                              = mode;         // mode of fileoperation (read,write)
1390
        file->Size                                              = 0;            // the size of the opened file in bytes.
1482
        file->Size                                              = 0;            // the size of the opened file in bytes.
1391
        file->Position                                  = 0;            // pointer to a byte within the file 0 < fileposition < filesize
1483
        file->Position                                  = 0;            // pointer to a byte within the file 0 < fileposition < filesize
1392
        file->SectorInCache                             = 0;            // the last sector read, wich is still in the sectorbuffer.
1484
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
1393
        file->DirectorySector                   = 0;            // the sectorposition where the directoryentry has been made.
1485
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
1394
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1486
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
Line 1395... Line 1487...
1395
        file->Attribute                                 = 0;            // the attribute of the file opened.
1487
        file->Attribute                                 = 0;            // the attribute of the file opened.
1396
 
1488
 
Line 1415... Line 1507...
1415
                                {       // file is marked as readonly --> do not open this file
1507
                                {       // file is marked as readonly --> do not open this file
1416
                                        fclose_(file);
1508
                                        fclose_(file);
1417
                                        file = NULL;
1509
                                        file = NULL;
1418
                                }
1510
                                }
1419
                                else
1511
                                else
1420
                                {       // file is not marked as read only --> goto start of file
1512
                                {       // file is not marked as read only
-
 
1513
                                        DirEntry_t * dir;
1421
                                        // free all clusters of that file
1514
                                        // free all clusters of that file
1422
                                        DeleteClusterChain(SectorToFat16Cluster(file->FirstSectorOfFirstCluster));
1515
                                        DeleteClusterChain(SectorToFat16Cluster(file->FirstSectorOfFirstCluster));
-
 
1516
                                        // update directory entry of that file
-
 
1517
                                        file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
-
 
1518
                                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
-
 
1519
                                        {
-
 
1520
                                                Fat16_Deinit();
-
 
1521
                                                return(NULL);
-
 
1522
                                        }
1423
                                        // mark an empy cluster as the last one and store the corresponding sector
1523
                                        dir = (DirEntry_t *)file->Cache;                                                                // set pointer to directory
-
 
1524
                                    dir[file->DirectoryIndex].ModTime   = FileTime(&SystemTime);        // set modification time
-
 
1525
                                        dir[file->DirectoryIndex].ModDate       = FileDate(&SystemTime);        // set modification date
-
 
1526
                                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
-
 
1527
                                        dir[file->DirectoryIndex].StartCluster = CLUSTER_UNDEFINED;             // update startcluster 
-
 
1528
                                        dir[file->DirectoryIndex].Size          = 0;
-
 
1529
                                        // write sector containing the direntry
-
 
1530
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
-
 
1531
                                        {
-
 
1532
                                                Fat16_Deinit();
-
 
1533
                                                return(NULL);
-
 
1534
                                        }
1424
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(FindNextFreeCluster(file));
1535
                                        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1425
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
1536
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
1426
                                        file->SectorOfCurrCluster = 0;
1537
                                        file->SectorOfCurrCluster = 0;
1427
                                        file->ByteOfCurrSector = 0;
1538
                                        file->ByteOfCurrSector = 0;
1428
                                        file->Size = 0;
1539
                                        file->Size = 0;
1429
                                        file->Position = 0;
1540
                                        file->Position = 0;
Line 1499... Line 1610...
1499
                                Fat16_Deinit();
1610
                                Fat16_Deinit();
1500
                                return(EOF);
1611
                                return(EOF);
1501
                        }
1612
                        }
Line 1502... Line 1613...
1502
 
1613
 
-
 
1614
                        dir = (DirEntry_t *)file->Cache;
-
 
1615
                        // update dile size and modification time & date
-
 
1616
                        dir[file->DirectoryIndex].ModTime = FileTime(&SystemTime);
-
 
1617
                        dir[file->DirectoryIndex].ModDate = FileDate(&SystemTime);
1503
                        dir = (DirEntry_t *)file->Cache;
1618
                        dir[file->DirectoryIndex].LastAccessDate = dir[file->DirectoryIndex].ModDate;
1504
                        dir[file->DirectoryIndex].Size = file->Size;                                            // update file size
-
 
1505
                        dir[file->DirectoryIndex].DateTime = FileDateTime(&SystemTime);         // update date time
1619
                        dir[file->DirectoryIndex].Size = file->Size;                                            // update file size
1506
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to sd-card
1620
                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to sd-card
1507
                        {
1621
                        {
1508
                                Fat16_Deinit();
1622
                                Fat16_Deinit();
1509
                                return(EOF);
1623
                                return(EOF);
1510
                        }
1624
                        }
1511
                        break;
1625
                        break;
1512
                case 'r':
1626
                case 'r':
-
 
1627
                default:
1513
                default:
1628
                        // do nothing!
1514
                        return(EOF);
1629
                        return(EOF);
Line 1515... Line 1630...
1515
                        break;
1630
                        break;
1516
 
1631
 
Line 1601... Line 1716...
1601
s16 fputc_(const s8 c, File_t *file)
1716
s16 fputc_(const s8 c, File_t *file)
1602
{
1717
{
1603
        u32 curr_sector  = 0;
1718
        u32 curr_sector  = 0;
Line 1604... Line 1719...
1604
 
1719
 
1605
        if((!Partition.IsValid) || (file == NULL)) return(EOF);
-
 
1606
 
-
 
1607
        // If file position equals to file size, then the end of file has reached.
-
 
1608
        // In this chase it has to be checked that the ByteOfCurrSector is BYTES_PER_SECTOR
-
 
1609
        // and a new cluster should be appended.
-
 
1610
        if((file->Position >= file->Size) && (file->ByteOfCurrSector >= BYTES_PER_SECTOR))
-
 
1611
        {
-
 
1612
                if(!AppendCluster(file)) return(EOF);
-
 
1613
        }
-
 
1614
 
-
 
1615
        curr_sector  = file->FirstSectorOfCurrCluster;
1720
        if((!Partition.IsValid) || (file == NULL)) return(EOF);
1616
        curr_sector += file->SectorOfCurrCluster;
-
 
1617
        if(file->SectorInCache != curr_sector)
1721
        switch(file->Mode)
1618
        {
-
 
1619
                file->SectorInCache = curr_sector;
-
 
1620
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))
-
 
1621
                {
1722
        {
1622
                        Fat16_Deinit();
1723
                case 'w':
1623
                        return(EOF);
-
 
1624
                }
-
 
1625
        }
-
 
1626
 
1724
                case 'a':
1627
        file->Cache[file->ByteOfCurrSector] = (u8)c;                    // write databyte into the buffer. The byte will be written to the device at once
-
 
1628
        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.
1725
                        // If file position equals to file size, then the end of file has been reached.
1629
        file->Position++;                                                                       // the actual positon within the file.
1726
                        // In this case it has to be checked that the ByteOfCurrSector is BYTES_PER_SECTOR
1630
        file->ByteOfCurrSector++;                                                       // goto next byte in sector
1727
                        // and a new cluster should be appended.
1631
        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
1728
                        // If the first sector of first cluster is unvalid, then the file claims no data clusters 
1632
        {       // save the sector to the sd-card
1729
                        // and size should be zero, therefore append a new Cluster too.
1633
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
1730
                        if(((file->Position >= file->Size) && (file->ByteOfCurrSector >= BYTES_PER_SECTOR)) || (file->FirstSectorOfFirstCluster == SECTOR_UNDEFINED))
1634
                {
-
 
1635
                        Fat16_Deinit();
1731
                        {
1636
                        return(EOF);
1732
                                if(CLUSTER_UNDEFINED == AppendCluster(file)) return(EOF);
-
 
1733
                        }
1637
                }
1734
               
1638
                file->ByteOfCurrSector = 0;                                             //  reset byte location
1735
                        curr_sector  = file->FirstSectorOfCurrCluster;
1639
                file->SectorOfCurrCluster++;                                    //      next sector
1736
                        curr_sector += file->SectorOfCurrCluster;
1640
                if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster)// if end of cluster is reached, the next datacluster has to be searched in the FAT.
1737
                        if(file->SectorInCache != curr_sector)
1641
                {
-
 
1642
                        if(!GetNextCluster(file))                                                               // Sets the clusterpointer of the file to the next datacluster.
1738
                        {
1643
                        { // if current cluster was the last cluster of the file
1739
                                file->SectorInCache = curr_sector;
1644
                                if(!AppendCluster(file))                                                // append a new and free cluster at the end of the file.
1740
                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))
1645
                                {
1741
                                {
1646
                                        file->SectorOfCurrCluster--;                            // jump back to last sector of last cluster
-
 
1647
                                        file->ByteOfCurrSector = BYTES_PER_SECTOR;      // set byte location to 1 byte over sector len
1742
                                        Fat16_Deinit();
1648
                                        return(EOF);
1743
                                        return(EOF);
1649
                                }
1744
                                }
-
 
1745
                        }
-
 
1746
               
-
 
1747
                        file->Cache[file->ByteOfCurrSector] = (u8)c;            // write databyte into the buffer. The byte will be written to the device at once
-
 
1748
                        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.
-
 
1749
                        file->Position++;                                                                       // the actual positon within the file.
-
 
1750
                        file->ByteOfCurrSector++;                                                       // goto next byte in sector
-
 
1751
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)          // if the end of this sector is reached yet
-
 
1752
                        {       // save the sector to the sd-card
-
 
1753
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
-
 
1754
                                {
-
 
1755
                                        Fat16_Deinit();
-
 
1756
                                        return(EOF);
-
 
1757
                                }
-
 
1758
                                file->ByteOfCurrSector = 0;                                             //  reset byte location
-
 
1759
                                file->SectorOfCurrCluster++;                                    //      next sector
-
 
1760
                                if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster)// if end of cluster is reached, the next datacluster has to be searched in the FAT.
-
 
1761
                                {
-
 
1762
                                        if(!GetNextCluster(file))                                                               // Sets the clusterpointer of the file to the next datacluster.
-
 
1763
                                        { // if current cluster was the last cluster of the file
-
 
1764
                                                if(!AppendCluster(file))                                                // append a new and free cluster at the end of the file.
-
 
1765
                                                {
-
 
1766
                                                        file->SectorOfCurrCluster--;                            // jump back to last sector of last cluster
-
 
1767
                                                        file->ByteOfCurrSector = BYTES_PER_SECTOR;      // set byte location to 1 byte over sector len
-
 
1768
                                                        return(EOF);
-
 
1769
                                                }
1650
                        }
1770
                                        }
1651
                        else // next cluster
1771
                                        else // next cluster
1652
                        {
1772
                                        {
-
 
1773
                                                file->SectorOfCurrCluster = 0;                                                  // start reading new cluster at first sector of the cluster.
-
 
1774
                                        }
1653
                                file->SectorOfCurrCluster = 0;                                                  // start reading new cluster at first sector of the cluster.
1775
                                }
1654
                        }
1776
                        }
-
 
1777
                        break;
-
 
1778
                case 'r':
-
 
1779
                default:
1655
                }
1780
                        return(EOF);
-
 
1781
                        break;
1656
        }
1782
        } // EOF switch(file->Mode)
1657
        return(0);
1783
        return(0);
Line 1658... Line 1784...
1658
}
1784
}
Line 1716... Line 1842...
1716
        u8 *pbuff           = 0;                                                                                                                // a pointer to the actual bufferposition.
1842
        u8 *pbuff           = 0;                                                                                                                // a pointer to the actual bufferposition.
1717
        u8 success      = 1;                                                                                                            // no error occured during write operation to the file.
1843
        u8 success      = 1;                                                                                                            // no error occured during write operation to the file.
1718
        s16 c;
1844
        s16 c;
Line 1719... Line 1845...
1719
 
1845
 
1720
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
-
 
-
 
1846
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
1721
 
1847
        if(file->Mode == 'r') return (0); // opened read only
Line 1722... Line 1848...
1722
        pbuff = (u8 *) buffer;                                                                                                          // cast the void pointer to an u8 *
1848
        pbuff = (u8 *) buffer;                                                                                                          // cast the void pointer to an u8 *
1723
 
1849
 
1724
        while((object_cnt < count) && success)
1850
        while((object_cnt < count) && success)
Line 1754... Line 1880...
1754
s16 fputs_(s8 * const string, File_t * const file)
1880
s16 fputs_(s8 * const string, File_t * const file)
1755
{
1881
{
1756
        u8 i=0;
1882
        u8 i=0;
1757
        s16 c = 0;
1883
        s16 c = 0;
Line 1758... Line 1884...
1758
 
1884
 
1759
        if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(0);
-
 
-
 
1885
        if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(EOF);
1760
 
1886
        if(file->Mode == 'r') return(EOF);
1761
        while((string[i] != 0)&& (c != EOF))
1887
        while((string[i] != 0)&& (c != EOF))
1762
        {
1888
        {
1763
                c = fputc_(string[i], file);
1889
                c = fputc_(string[i], file);
1764
                i++;
1890
                i++;