Subversion Repositories NaviCtrl

Rev

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

Rev 363 Rev 368
Line 52... Line 52...
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
#include <stdio.h>
56
#include <stdio.h>
57
#include <string.h>
-
 
58
#include "91x_lib.h"
57
#include "91x_lib.h"
59
#include "timer1.h"
58
#include "timer1.h"
60
#include "fat16.h"
59
#include "fat16.h"
61
#include "sdc.h"
60
#include "sdc.h"
62
#include "uart1.h"
61
#include "uart1.h"
63
#include "main.h"
62
#include "logging.h"
64
 
-
 
65
//________________________________________________________________________________________________________________________________________
63
//________________________________________________________________________________________________________________________________________
66
// Module name:                 fat16.c
64
// Module name:                 fat16.c
67
// Compiler used:               avr-gcc 3.4.5
65
// Compiler used:               avr-gcc 3.4.5
68
// Last Modifikation:   20.03.2010
66
// Last Modifikation:   20.03.2010
69
// Version:                             2.10
67
// Version:                             2.10
Line 105... Line 103...
105
Root Directory Entry                            Start + # of Reserved + (# of Sectors Per FAT * 2)
103
Root Directory Entry                            Start + # of Reserved + (# of Sectors Per FAT * 2)
106
Data Area (Starts with Cluster #2)      Start + # of Reserved + (# of Sectors Per FAT * 2) + ((Maximum Root Directory Entries * 32) / Bytes per Sector)
104
Data Area (Starts with Cluster #2)      Start + # of Reserved + (# of Sectors Per FAT * 2) + ((Maximum Root Directory Entries * 32) / Bytes per Sector)
107
*/
105
*/
Line 108... Line -...
108
 
-
 
109
 
106
 
110
 
107
 
Line 111... Line 108...
111
/*
108
/*
112
________________________________________________________________________________________________________________________________________
109
________________________________________________________________________________________________________________________________________
Line 126... Line 123...
126
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
123
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
127
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
124
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
128
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
125
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
129
} __attribute__((packed)) PartitionEntry_t;
126
} __attribute__((packed)) PartitionEntry_t;
Line 130... Line -...
130
 
-
 
131
 
-
 
132
 
127
 
133
/*
128
/*
Line 134... Line 129...
134
Coding of Cylinder/Sector words
129
Coding of Cylinder/Sector words
135
 
130
 
Line 311... Line 306...
311
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
306
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
312
        u32 FirstFatSector;                     // sector of the start of the fat
307
        u32 FirstFatSector;                     // sector of the start of the fat
313
        u32 FirstRootDirSector;         // sector of the rootdirectory
308
        u32 FirstRootDirSector;         // sector of the rootdirectory
314
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
309
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
315
        u32 LastDataSector;                     // the last data sector of the partition
310
        u32 LastDataSector;                     // the last data sector of the partition
316
        u8  VolumeLabel[12];        // the volume label
311
        u8 VolumeLabel[12];                     // the volume label
317
        u32     CurrentWorkingDirectory;// A pointer to the directory we are actual using 
-
 
318
        s8      PathToCwd[256];                 // a string containing the complete path to the current working directory                               
-
 
319
}   __attribute__((packed)) Partition_t;
312
} Partition_t;
Line 320... Line 313...
320
 
313
 
Line 321... Line 314...
321
Partition_t     Partition;              // Structure holds partition information
314
Partition_t     Partition;                                      // Structure holds partition information
Line 322... Line -...
322
 
-
 
323
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
-
 
324
 
315
 
325
 
316
File_t FilePointer[FILE_MAX_OPEN];      // Allocate Memmoryspace for each filepointer used.
326
 
317
 
327
 
318
 
328
/****************************************************************************************************************************************/
319
/****************************************************************************************************************************************/
Line 438... Line 429...
438
 
429
 
439
        // search subpath from beginning of filepath
430
        // search subpath from beginning of filepath
440
        subpath = NULL;
431
        subpath = NULL;
441
        readpointer     = 0;
432
        readpointer     = 0;
442
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
433
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
443
        while(subpath == NULL && (SD_WatchDog)) // search the filepath until a subpath was found.
434
        while(subpath == NULL)  // search the filepath until a subpath was found.
444
        {
435
        {
445
                if(((filepath[readpointer] == 0) || (filepath[readpointer] == '/')))    // if '/' found or end of filepath reached
436
                if(((filepath[readpointer] == 0) || (filepath[readpointer] == '/')))    // if '/' found or end of filepath reached
446
                {
437
                {
447
                        subpath = (s8*)&filepath[readpointer];                          // store the position of the first "/" found after the beginning of the filenpath
438
                        subpath = (s8*)&filepath[readpointer];                          // store the position of the first "/" found after the beginning of the filenpath
Line 450... Line 441...
450
        }
441
        }
Line 451... Line 442...
451
 
442
 
452
        // clear dirname with spaces
443
        // clear dirname with spaces
453
        dirname[11] = 0; // terminate dirname
444
        dirname[11] = 0; // terminate dirname
454
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
-
 
455
 
-
 
456
        // handle the special dirnames "." and ".." seperately
-
 
457
        readpointer = 0;
-
 
458
        if(filepath[0] == '/') readpointer++;
-
 
459
        // if we are trying to enter directories "." or ".." 
-
 
460
        if(filepath[readpointer] == '.')
-
 
461
        {
-
 
462
                // directory '.'
-
 
463
                if(filepath[readpointer+1] == 0)
-
 
464
                {
-
 
465
                        dirname[0] = '.';
-
 
466
                        return((s8*)&filepath[readpointer]);
-
 
467
                }
-
 
468
                // directory '..'               
-
 
469
                if((filepath[readpointer+1] == '.') &&  (filepath[readpointer+2] == 0))
-
 
470
                {
-
 
471
                        dirname[0] = '.';
-
 
472
                        dirname[1] = '.';
-
 
473
                        return((s8*)&filepath[readpointer]);
-
 
474
                }
-
 
475
        }
-
 
476
 
445
        for(writepointer = 0; writepointer < 11; writepointer++) dirname[writepointer] = ' ';
477
        writepointer = 0;
446
        writepointer = 0;
478
        // start seperating the dirname from the filepath.
447
        // start seperating the dirname from the filepath.
479
        readpointer = 0;
448
        readpointer = 0;
480
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
449
        if(filepath[0] == '/') readpointer = 1; // ignore first '/'
481
        while( &filepath[readpointer] < subpath && (SD_WatchDog))
450
        while( &filepath[readpointer] < subpath)
482
        {
451
        {
483
                if(writepointer >= 11) return(NULL);            // dirname to long
452
                if(writepointer >= 11) return(NULL);            // dirname to long
484
                if(filepath[readpointer] == '.')                        // seperating dirname and extension.
453
                if(filepath[readpointer] == '.')                        // seperating dirname and extension.
485
                {
454
                {
Line 577... Line 546...
577
        }
546
        }
578
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
547
        returnvalue = SDC_Deinit();                     // uninitialize interface to sd-card
579
        Partition.IsValid = 0;  // mark data in partition structure as invalid
548
        Partition.IsValid = 0;  // mark data in partition structure as invalid
580
        Partition.VolumeLabel[0]='\0';
549
        Partition.VolumeLabel[0]='\0';
581
        UART1_PutString("ok");
550
        UART1_PutString("ok");
-
 
551
        SD_LoggingError = 100;
582
        return(returnvalue);
552
        return(returnvalue);
583
}
553
}
Line 584... Line 554...
584
 
554
 
585
/****************************************************************************************************************************************/
555
/****************************************************************************************************************************************/
Line 599... Line 569...
599
        File_t *file;
569
        File_t *file;
600
        u8 result = 0;
570
        u8 result = 0;
Line 601... Line 571...
601
 
571
 
602
        UART1_PutString("\r\n FAT16 init...");
572
        UART1_PutString("\r\n FAT16 init...");
-
 
573
        Partition.IsValid = 0;
603
        Partition.IsValid = 0;
574
 
604
        // declare the filepointers as unused.
575
        // declare the filepointers as unused.
605
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
576
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
606
        {
577
        {
607
                UnlockFilePointer(&FilePointer[cnt]);
578
                UnlockFilePointer(&FilePointer[cnt]);
Line 681... Line 652...
681
                UART1_PutString("VBR: Partition ist not FAT16 type.");
652
                UART1_PutString("VBR: Partition ist not FAT16 type.");
682
                result = 6;
653
                result = 6;
683
                goto end;
654
                goto end;
684
        }
655
        }
685
        Partition.IsValid = 1; // mark data in partition structure as valid
656
        Partition.IsValid = 1; // mark data in partition structure as valid
686
        Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
687
        strcpy(Partition.PathToCwd,"/");       
-
 
688
        result = 0;
657
        result = 0;
689
        end:
658
        end:
690
        if(result != 0) Fat16_Deinit();
659
        if(result != 0) Fat16_Deinit();
691
        else UART1_PutString("ok");
660
        else UART1_PutString("ok");
692
        return(result);
661
        return(result);
Line 714... Line 683...
714
        {
683
        {
715
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
684
                file->SectorInCache = file->FirstSectorOfCurrCluster + i;
716
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
685
                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))
717
                {
686
                {
718
                        Fat16_Deinit();
687
                        Fat16_Deinit();
-
 
688
                        retvalue = 0;
719
                        return(0);
689
                        return(retvalue);
720
                }
690
                }
721
        }
691
        }
722
        return(retvalue);
692
        return(retvalue);
723
}
693
}
Line 753... Line 723...
753
                {
723
                {
754
                        file->SectorInCache = sector;                                           // update sector stored in buffer
724
                        file->SectorInCache = sector;                                           // update sector stored in buffer
755
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
725
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))       // read sector from sd-card
756
                        {
726
                        {
757
                                Fat16_Deinit();
727
                                Fat16_Deinit();
758
                                return (CLUSTER_UNDEFINED);
728
                                return (cluster);
759
                        }
729
                        }
760
                }
730
                }
761
                // read the next cluster from cache
731
                // read the next cluster from cache
762
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
732
                fat = (Fat16Entry_t *)(&(file->Cache[byte]));
763
                cluster = fat->NextCluster;
733
                cluster = fat->NextCluster;
Line 775... Line 745...
775
        }
745
        }
776
        return(cluster);
746
        return(cluster);
777
}
747
}
Line 778... Line -...
778
 
-
 
779
 
748
 
780
 
749
 
781
/****************************************************************************************************************************************/
750
/****************************************************************************************************************************************/
782
/* Function:    FindNextFreeCluster(File_t *);                                                                                                                                                                          */
751
/* Function:    FindNextFreeCluster(File_t *);                                                                                                                                                                          */
783
/*                                                                                                                                                                                                                                                                              */
752
/*                                                                                                                                                                                                                                                                              */
Line 802... Line 771...
802
                curr_sector = Partition.FirstFatSector + fat_sector;    // calculate sector to read
771
                curr_sector = Partition.FirstFatSector + fat_sector;    // calculate sector to read
803
                file->SectorInCache = curr_sector;                                              // upate the sector number of file cache.
772
                file->SectorInCache = curr_sector;                                              // upate the sector number of file cache.
804
                if( SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))              // read sector of fat from sd-card.
773
                if( SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))              // read sector of fat from sd-card.
805
                {
774
                {
806
                        Fat16_Deinit();
775
                        Fat16_Deinit();
807
                        return(CLUSTER_UNDEFINED);
776
                        return(free_cluster);
808
                }
777
                }
Line 809... Line 778...
809
 
778
 
Line 810... Line 779...
810
                fat = (Fat16Entry_t *)file->Cache;                                              // set fat pointer to file cache
779
                fat = (Fat16Entry_t *)file->Cache;                                              // set fat pointer to file cache
Line 815... Line 784...
815
                        {
784
                        {
816
                                fat[fat_entry].NextCluster = FAT16_CLUSTER_LAST_MAX;    // mark this fat-entry as used
785
                                fat[fat_entry].NextCluster = FAT16_CLUSTER_LAST_MAX;    // mark this fat-entry as used
817
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // and save the sector at the sd-card.
786
                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))               // and save the sector at the sd-card.
818
                                {
787
                                {
819
                                        Fat16_Deinit();
788
                                        Fat16_Deinit();
820
                                        return(CLUSTER_UNDEFINED);
789
                                        return(free_cluster);
821
                                }
790
                                }
822
                                free_cluster = (u16)(fat_sector * FAT16_ENTRIES_PER_SECTOR + (u32)fat_entry);
791
                                free_cluster = (u16)(fat_sector * FAT16_ENTRIES_PER_SECTOR + (u32)fat_entry);
823
                                fat_entry = FAT16_ENTRIES_PER_SECTOR;                                   // terminate the search for a free cluster in this sector.
792
                                fat_entry = FAT16_ENTRIES_PER_SECTOR;                                   // terminate the search for a free cluster in this sector.
824
                        }
793
                        }
825
                }
794
                }
826
                fat_sector++;                                                                                                   // continue the search in next fat sector
795
                fat_sector++;                                                                                                   // continue the search in next fat sector
827
        // repeat until the end of the fat is  reached and no free cluster has been found so far
796
        // repeat until the end of the fat is  reached and no free cluster has been found so far
828
        }while((fat_sector < Partition.SectorsPerFat) && (!free_cluster) && (SD_WatchDog));
797
        }while((fat_sector < Partition.SectorsPerFat) && (!free_cluster));
829
        return(free_cluster);
798
        return(free_cluster);
830
}
799
}
Line 831... Line 800...
831
 
800
 
Line 865... Line 834...
865
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
834
                file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
866
                file->SectorOfCurrCluster       = 0;
835
                file->SectorOfCurrCluster       = 0;
867
                file->ByteOfCurrSector          = 0;
836
                file->ByteOfCurrSector          = 0;
868
                file->Position                          = 0;
837
                file->Position                          = 0;
869
                if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
838
                if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
870
                while(file->Position < fposition && (SD_WatchDog))      // repeat until the current position is less than target
839
                while(file->Position < fposition)       // repeat until the current position is less than target
871
                {
840
                {
872
                        file->Position++;                               // increment file position
841
                        file->Position++;                               // increment file position
873
                        file->ByteOfCurrSector++;               // next byte in current sector
842
                        file->ByteOfCurrSector++;               // next byte in current sector
874
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
843
                        if(file->ByteOfCurrSector >= BYTES_PER_SECTOR)
875
                        {
844
                        {
Line 955... Line 924...
955
                                Fat16_Deinit();
924
                                Fat16_Deinit();
956
                                return(0);
925
                                return(0);
957
                        }
926
                        }
958
                }
927
                }
959
        }
928
        }
960
        while(repeat && (SD_WatchDog));
929
        while(repeat);
Line 961... Line 930...
961
 
930
 
962
        return 1;
931
        return 1;
Line 1066... Line 1035...
1066
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
1035
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
Line 1067... Line 1036...
1067
 
1036
 
1068
        // dir entries can be searched only in filesclusters that have
1037
        // dir entries can be searched only in filesclusters that have
1069
        // a corresponding dir entry with adir-flag set in its attribute
1038
        // a corresponding dir entry with adir-flag set in its attribute
-
 
1039
        // or direct within the root directory area
1070
        // or direct within the root directory area
1040
 
1071
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1041
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1072
        // no current directory exist therefore assume searching in the root
1042
        // no current directory exist therefore assume searching in the root
1073
        if(file->DirectorySector == SECTOR_UNDEFINED)
1043
        if(file->DirectorySector == SECTOR_UNDEFINED)
1074
        {
1044
        {
Line 1092... Line 1062...
1092
                // check if the directory entry of current file is existent and has the dir-flag set
1062
                // check if the directory entry of current file is existent and has the dir-flag set
1093
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1063
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1094
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1064
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1095
                {
1065
                {
1096
                        Fat16_Deinit();
1066
                        Fat16_Deinit();
1097
                        return(0);
1067
                        return(direntry_exist);
1098
                }
1068
                }
1099
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1069
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1100
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1070
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1101
                {
1071
                {
1102
                        case SLOT_EMPTY:
1072
                        case SLOT_EMPTY:
Line 1120... Line 1090...
1120
        file->SectorOfCurrCluster               = 0;
1090
        file->SectorOfCurrCluster               = 0;
1121
        file->ByteOfCurrSector                  = 0;
1091
        file->ByteOfCurrSector                  = 0;
Line 1122... Line 1092...
1122
 
1092
 
1123
        do // loop over all data clusters of the current directory entry
1093
        do // loop over all data clusters of the current directory entry
1124
        {
1094
        {
1125
                dir_sector = 0;
1095
                dir_sector = 0; // reset sector counter within a new cluster
1126
                do // loop over all sectors of a cluster or all sectors of the root directory
1096
                do // loop over all sectors of a cluster or all sectors of the root directory
1127
                {
1097
                {
1128
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1098
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1129
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1099
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1130
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
1100
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
1131
                        {
1101
                        {
1132
                                Fat16_Deinit();
1102
                                Fat16_Deinit();
1133
                                return(0);
1103
                                return(direntry_exist);
1134
                        }
1104
                        }
1135
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1105
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1136
                        // search all directory entries within that sector
1106
                        // search all directory entries within that sector
1137
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
1107
                        for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
Line 1162... Line 1132...
1162
                                                dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1132
                                                dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1163
                                } // end of first byte of name check
1133
                                } // end of first byte of name check
1164
                        }
1134
                        }
1165
                        dir_sector++; // search next sector
1135
                        dir_sector++; // search next sector
1166
                // stop if we reached the end of the cluster or the end of the root dir
1136
                // stop if we reached the end of the cluster or the end of the root dir
1167
                }while((dir_sector < max_dir_sector) && (!direntry_exist) && (SD_WatchDog));
1137
                }while((dir_sector < max_dir_sector) && (!direntry_exist));
Line 1168... Line 1138...
1168
 
1138
 
1169
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1139
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1170
                if(!direntry_exist && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1140
                if(!direntry_exist && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1171
                {
1141
                {
1172
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1142
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1173
                }
1143
                }
1174
        }while((end_of_directory_not_reached) && (!direntry_exist) && (SD_WatchDog)); // repeat until a next cluster exist an no
1144
        }while((end_of_directory_not_reached) && (!direntry_exist)); // repeat until a next cluster exist an no
1175
        return(direntry_exist);
1145
        return(direntry_exist);
Line 1176... Line 1146...
1176
}
1146
}
Line 1225... Line 1195...
1225
            // check if the directory entry of current file is existent and has the dir-flag set
1195
            // check if the directory entry of current file is existent and has the dir-flag set
1226
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1196
                file->SectorInCache = file->DirectorySector;                            // update the sector number of file cache.
1227
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1197
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1228
                {
1198
                {
1229
                        Fat16_Deinit();
1199
                        Fat16_Deinit();
1230
                        return(0);
1200
                        return(retvalue);
1231
                }
1201
                }
1232
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1202
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1233
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1203
                switch((u8)dir[file->DirectoryIndex].Name[0])                           // check if current directory exist
1234
                {
1204
                {
1235
                        case SLOT_EMPTY:
1205
                        case SLOT_EMPTY:
Line 1267... Line 1237...
1267
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1237
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1268
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1238
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1269
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1239
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1270
                        {
1240
                        {
1271
                                Fat16_Deinit();
1241
                                Fat16_Deinit();
1272
                                return(0);
1242
                                return(retvalue);
1273
                        }
1243
                        }
Line 1274... Line 1244...
1274
 
1244
 
1275
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1245
                        dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
1276
                        // search all directory entries of a sector
1246
                        // search all directory entries of a sector
Line 1293... Line 1263...
1293
                                        dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
1263
                                        dir[dir_entry].StartCluster = subdircluster;                                            // copy the location of the first datacluster to the directoryentry.
1294
                                        dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
1264
                                        dir[dir_entry].Size             = 0;                                                                    // the new createted file has no content yet.
1295
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
1265
                                        if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))       // write back to card
1296
                                        {
1266
                                        {
1297
                                                Fat16_Deinit();
1267
                                                Fat16_Deinit();
1298
                                                return(0);
1268
                                                return(retvalue);
1299
                                        }
1269
                                        }
1300
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
1270
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(subdircluster);  // Calculate absolute sectorposition of first datacluster.
1301
                                        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1271
                                        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;      // Start reading the file with the first sector of the first datacluster.
1302
                                        file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
1272
                                        file->SectorOfCurrCluster               = 0;                                                            // reset sector of cureen cluster
1303
                                        file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
1273
                                        file->ByteOfCurrSector                  = 0;                                                            // reset the byte location within the current sector
Line 1311... Line 1281...
1311
                                                ClearCurrCluster(file); // fill cluster with zeros
1281
                                                ClearCurrCluster(file); // fill cluster with zeros
1312
                                                file->SectorInCache = file->FirstSectorOfFirstCluster;
1282
                                                file->SectorInCache = file->FirstSectorOfFirstCluster;
1313
                                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1283
                                                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read in the sector.
1314
                                                {
1284
                                                {
1315
                                                        Fat16_Deinit();
1285
                                                        Fat16_Deinit();
1316
                                                        return(0);
1286
                                                        return(retvalue);
1317
                                                }
1287
                                                }
1318
                                                dir = (DirEntry_t *)file->Cache;
1288
                                                dir = (DirEntry_t *)file->Cache;
1319
                                                // create direntry "." to current dir
1289
                                                // create direntry "." to current dir
1320
                                                dir[0].Name[0] = 0x2E;
1290
                                                dir[0].Name[0] = 0x2E;
1321
                                                for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
1291
                                                for(i = 1; i < 11; i++) dir[0].Name[i] = ' ';
Line 1330... Line 1300...
1330
                                                dir[1].StartCluster = dircluster;
1300
                                                dir[1].StartCluster = dircluster;
1331
                                                dir[1].Size = 0;
1301
                                                dir[1].Size = 0;
1332
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
1302
                                                if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache))// read in the sector.
1333
                                                {
1303
                                                {
1334
                                                        Fat16_Deinit();
1304
                                                        Fat16_Deinit();
1335
                                                        return(0);
1305
                                                        return(retvalue);
1336
                                                }
1306
                                                }
1337
                                        }
1307
                                        }
1338
                                        retvalue = 1;
1308
                                        retvalue = 1;
1339
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1309
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
1340
                                }
1310
                                }
1341
                        }
1311
                        }
1342
                        dir_sector++; // search next sector
1312
                        dir_sector++; // search next sector
1343
                // stop if we reached the end of the cluster or the end of the root dir
1313
                // stop if we reached the end of the cluster or the end of the root dir
1344
                }while((dir_sector < max_dir_sector) && (!retvalue) && (SD_WatchDog));
1314
                }while((dir_sector < max_dir_sector) && (!retvalue));
Line 1345... Line 1315...
1345
 
1315
 
1346
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1316
                // if we are seaching in the data area and the file not found in this cluster so take next cluster.
1347
                if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1317
                if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1348
                {
1318
                {
1349
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1319
                        end_of_directory_not_reached = GetNextCluster(file);  // updates File->FirstSectorOfCurrCluster
1350
                }
1320
                }
1351
        }while((end_of_directory_not_reached) && (!retvalue) && (SD_WatchDog));
1321
        }while((end_of_directory_not_reached) && (!retvalue));
1352
        // Perhaps we are at the end of the last cluster of a directory file and have no free direntry found.
1322
        // Perhaps we are at the end of the last cluster of a directory file and have no free direntry found.
1353
        // Then we would need to add a cluster to that file and create the new direntry there.
1323
        // Then we would need to add a cluster to that file and create the new direntry there.
1354
        // This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
1324
        // This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
Line 1378... Line 1348...
1378
 
1348
 
1379
        // trace along the filepath
1349
        // trace along the filepath
1380
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1350
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1381
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1351
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1382
        file->DirectoryIndex = 0;
-
 
1383
        /* if a path begins with a '/' at index 0 the search starts at the rootdirectory otherwise we will start relative to the cwd */
-
 
1384
        if(path[0] != '/')
-
 
1385
        {
-
 
1386
                /* is the current working directory the rootdirectory? */
-
 
1387
                if(Partition.CurrentWorkingDirectory == Partition.FirstRootDirSector) file->DirectorySector = 0;
-
 
1388
                /* otherwise we are working in an subdirectory */
-
 
1389
                else file->DirectorySector = Partition.CurrentWorkingDirectory;
-
 
1390
        }
1352
        file->DirectoryIndex = 0;
1391
        // as long as the file was not found and the remaining path is not empty
1353
        // as long as the file was not found and the remaining path is not empty
1392
        while((*path != 0) && !file_exist && (SD_WatchDog))
1354
        while((*path != 0) && !file_exist)
1393
        {       // separate dirname and subpath from filepath string
1355
        {       // separate dirname and subpath from filepath string
1394
                subpath = SeperateDirName(path, dirname);
1356
                subpath = SeperateDirName(path, dirname);
1395
                if(subpath != NULL)
1357
                if(subpath != NULL)
1396
                {
1358
                {
Line 1449... Line 1411...
1449
        // trace along the filepath
1411
        // trace along the filepath
1450
        path = (s8*)filename;                                                                   // start a the beginning of the filename string
1412
        path = (s8*)filename;                                                                   // start a the beginning of the filename string
1451
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1413
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1452
        file->DirectoryIndex = 0;
1414
        file->DirectoryIndex = 0;
1453
        // as long as the file was not created and the remaining file path is not empty
1415
        // as long as the file was not created and the remaining file path is not empty
1454
        while((*path != 0) && !file_created && (SD_WatchDog))
1416
        while((*path != 0) && !file_created)
1455
        {   // separate dirname and subpath from filepath string
1417
        {   // separate dirname and subpath from filepath string
1456
                subpath = SeperateDirName(path, dirname);
1418
                subpath = SeperateDirName(path, dirname);
1457
                if(subpath != NULL)
1419
                if(subpath != NULL)
1458
                {
1420
                {
1459
                        if(*subpath == 0)
1421
                        if(*subpath == 0)
Line 1496... Line 1458...
1496
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1458
/*      Returnvalue:    The filepointer to the file or 0 if faild.                                                                                                                                                              */
1497
/********************************************************************************************************************************************/
1459
/********************************************************************************************************************************************/
1498
File_t * fopen_(s8 * const filename, const s8 mode)
1460
File_t * fopen_(s8 * const filename, const s8 mode)
1499
{
1461
{
1500
        File_t *file    = 0;
1462
        File_t *file    = 0;
1501
        s8 *cptr;
-
 
Line 1502... Line 1463...
1502
 
1463
 
Line 1503... Line 1464...
1503
        if((!Partition.IsValid) || (filename == 0)) return(file);
1464
        if((!Partition.IsValid) || (filename == 0)) return(file);
1504
 
1465
 
Line 1519... Line 1480...
1519
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
1480
        file->SectorInCache                             = SECTOR_UNDEFINED;             // the last sector read, wich is still in the sectorbuffer.
1520
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
1481
        file->DirectorySector                   = SECTOR_UNDEFINED;             // the sectorposition where the directoryentry has been made.
1521
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1482
        file->DirectoryIndex                    = 0;            // the index to the directoryentry within the specified sector.
1522
        file->Attribute                                 = 0;            // the attribute of the file opened.
1483
        file->Attribute                                 = 0;            // the attribute of the file opened.
Line 1523... Line -...
1523
 
-
 
1524
        // bring the path into the correct syntax 
-
 
1525
        cptr = filename;
-
 
1526
        // search the whole string 
-
 
1527
        while(*cptr != 0 && (SD_WatchDog))
-
 
1528
        {
-
 
1529
                // replace all '\' by '/'
-
 
1530
                if(*cptr == '\\') *cptr = '/';
-
 
1531
                cptr++;
-
 
1532
        }
1484
 
1533
        // check if a real file (no directory) to the given filename exist
1485
        // check if a real file (no directory) to the given filename exist
1534
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1486
        if(FileExist(filename, ATTR_NONE, ATTR_SUBDIRECTORY|ATTR_VOLUMELABEL, file))
1535
        {  // file exist
1487
        {  // file exist
1536
                switch(mode)  // check mode
1488
                switch(mode)  // check mode
Line 1605... Line 1557...
1605
                                // try to create the file
1557
                                // try to create the file
1606
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1558
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1607
                                { // if it could not be created
1559
                                { // if it could not be created
1608
                                        fclose_(file);
1560
                                        fclose_(file);
1609
                                        file = NULL;
1561
                                        file = NULL;
1610
                                }
1562
                                }
1611
                                break;
1563
                                break;
1612
                        case 'r': // else opened for 'r'
1564
                        case 'r': // else opened for 'r'
1613
                        default:  // if unsupported mode
1565
                        default:  // if unsupported mode
1614
                                fclose_(file);
1566
                                fclose_(file);
1615
                                file = NULL;
1567
                                file = NULL;
Line 1708... Line 1660...
1708
        s16 c = EOF;
1660
        s16 c = EOF;
1709
        u32 curr_sector;
1661
        u32 curr_sector;
Line 1710... Line 1662...
1710
 
1662
 
1711
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1663
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1712
        // if the end of the file is not reached, get the next character.
1664
        // if the end of the file is not reached, get the next character.
1713
        if((0 < file->Size) && ((file->Position) < file->Size) )
1665
        if((0 < file->Size) && ((file->Position+1) < file->Size) )
1714
        {
1666
        {
1715
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
1667
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
Line 1716... Line 1668...
1716
                curr_sector += file->SectorOfCurrCluster;
1668
                curr_sector += file->SectorOfCurrCluster;
1717
 
1669
 
1718
                if(file->SectorInCache != curr_sector)
1670
                if(file->SectorInCache != curr_sector)
1719
                {
1671
                {
1720
                        file->SectorInCache = curr_sector;
1672
                        file->SectorInCache = curr_sector;
1721
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache,file->Cache))
1673
                        if(SD_SUCCESS != SDC_GetSector(file->SectorInCache,file->Cache))
1722
                        {
1674
                        {
1723
                                Fat16_Deinit();
1675
                                Fat16_Deinit();
1724
                                return(EOF);
1676
                                return(c);
1725
                        }
1677
                        }
1726
                }
1678
                }
1727
                c = (s16) file->Cache[file->ByteOfCurrSector];
1679
                c = (s16) file->Cache[file->ByteOfCurrSector];
Line 1846... Line 1798...
1846
 
1798
 
Line 1847... Line 1799...
1847
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
1799
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
Line 1848... Line 1800...
1848
 
1800
 
1849
        pbuff = (u8 *) buffer;                                                                                  // cast the void pointer to an u8 *
1801
        pbuff = (u8 *) buffer;                                                                                  // cast the void pointer to an u8 *
1850
 
1802
 
1851
        while((object_cnt < count) && success && (SD_WatchDog))
1803
        while((object_cnt < count) && success)
1852
        {
1804
        {
1853
                object_size = size;
1805
                object_size = size;
1854
                while((size > 0) && success && (SD_WatchDog))
1806
                while((size > 0) && success)
1855
                {
1807
                {
1856
                        c = fgetc_(file);
1808
                        c = fgetc_(file);
Line 1889... Line 1841...
1889
 
1841
 
1890
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
1842
        if((!Partition.IsValid) || (file == NULL) || (buffer == NULL)) return(0);
1891
        if(file->Mode == 'r') return (0); // opened read only
1843
        if(file->Mode == 'r') return (0); // opened read only
Line 1892... Line 1844...
1892
        pbuff = (u8 *) buffer;                                                                                                          // cast the void pointer to an u8 *
1844
        pbuff = (u8 *) buffer;                                                                                                          // cast the void pointer to an u8 *
1893
 
1845
 
1894
        while((object_cnt < count) && success && (SD_WatchDog))
1846
        while((object_cnt < count) && success)
1895
        {
1847
        {
1896
                object_size = size;
1848
                object_size = size;
1897
                while((size > 0) && success && (SD_WatchDog))
1849
                while((size > 0) && success)
1898
                {
1850
                {
1899
                        c = fputc_(*pbuff, file);                                                                               // write a byte from the buffer to the opened file.
1851
                        c = fputc_(*pbuff, file);                                                                               // write a byte from the buffer to the opened file.
1900
                        if(c != EOF)
1852
                        if(c != EOF)
Line 1926... Line 1878...
1926
        u8 i=0;
1878
        u8 i=0;
1927
        s16 c = 0;
1879
        s16 c = 0;
Line 1928... Line 1880...
1928
 
1880
 
1929
        if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(EOF);
1881
        if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(EOF);
1930
        if(file->Mode == 'r') return(EOF);
1882
        if(file->Mode == 'r') return(EOF);
1931
        while((string[i] != 0)&& (c != EOF) && (SD_WatchDog))
1883
        while((string[i] != 0)&& (c != EOF))
1932
        {
1884
        {
1933
                c = fputc_(string[i], file);
1885
                c = fputc_(string[i], file);
1934
                i++;
1886
                i++;
1935
        }
1887
        }
Line 1949... Line 1901...
1949
        s16 c = 0, bytecount;
1901
        s16 c = 0, bytecount;
Line 1950... Line 1902...
1950
 
1902
 
1951
        if((!Partition.IsValid) || (file == NULL) || (string == NULL) || (length < 1)) return (0);
1903
        if((!Partition.IsValid) || (file == NULL) || (string == NULL) || (length < 1)) return (0);
1952
        bytecount = length;
1904
        bytecount = length;
1953
        pbuff = string;                                                         // set write pointer to start of string
1905
        pbuff = string;                                                         // set write pointer to start of string
1954
        while(bytecount > 1 && (SD_WatchDog))                                           // read the length-1 characters from the file to the string.
1906
        while(bytecount > 1)                                            // read the length-1 characters from the file to the string.
1955
        {
1907
        {
1956
                c = fgetc_(file);                                               // read a character from the opened file.
1908
                c = fgetc_(file);                                               // read a character from the opened file.
1957
                switch(c)
1909
                switch(c)
1958
                {
1910
                {
Line 2050... Line 2002...
2050
                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
2002
                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
2051
                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
2003
                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
2052
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
2004
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
2053
                {
2005
                {
2054
                        Fat16_Deinit();
2006
                        Fat16_Deinit();
2055
                        return(NULL);
2007
                        return(pVolumeLabel);
2056
                }
2008
                }
2057
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
2009
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
2058
                // search all directory entries within that sector
2010
                // search all directory entries within that sector
2059
                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
2011
                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
2060
                {   // check for existing dir entry
2012
                {   // check for existing dir entry
Line 2082... Line 2034...
2082
                                        pVolumeLabel =  Partition.VolumeLabel;
2034
                                        pVolumeLabel =  Partition.VolumeLabel;
2083
                        } // end of first byte of name check
2035
                        } // end of first byte of name check
2084
                }
2036
                }
2085
                dir_sector++; // search next sector
2037
                dir_sector++; // search next sector
2086
        // stop if we reached the end of the cluster or the end of the root dir
2038
        // stop if we reached the end of the cluster or the end of the root dir
2087
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel) && (SD_WatchDog));
2039
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
Line 2088... Line 2040...
2088
 
2040
 
2089
        UnlockFilePointer(file);
2041
        UnlockFilePointer(file);
2090
        return(pVolumeLabel);
2042
        return(pVolumeLabel);
2091
}
-
 
2092
 
-
 
2093
 
-
 
2094
 
-
 
2095
#define ATTR_NONE               0x00    // normal file
-
 
2096
#define ATTR_READONLY           0x01    // file is readonly
-
 
2097
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2098
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2099
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2100
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2101
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2102
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2103
 
-
 
2104
 
-
 
2105
/********************************************************************************************************************************************/
-
 
2106
/*      Function:               u8 FindItem(Find_t);                                                                                                                                                                                                                    */
-
 
2107
/*                                                                                                                                                                                                                                                                                      */
-
 
2108
/*      Description:    This function looks for the item specified by global structure FindElement in the actual directory                                      */
-
 
2109
/*                                                                                                                                                                                                                                                              */
-
 
2110
/*                                                                                                                                                                                                                                                                                      */
-
 
2111
/*      Returnvalue:    TRUE if an matching element was found                                                                                                                                                                           */
-
 
2112
/********************************************************************************************************************************************/
-
 
2113
 
-
 
2114
u8 FindItem(Find_t *findelement)
-
 
2115
{
-
 
2116
        u16             index = 0;
-
 
2117
        u16             max_dir_sector = 0;
-
 
2118
        u16     end_of_directory_not_reached = 1;                                                                               // the directory has been read completely without a result.
-
 
2119
        u8              i = 0;
-
 
2120
        u8              readpointer = 0;
-
 
2121
        u8              writepointer = 0;
-
 
2122
        u8              retvalue = 0;
-
 
2123
        DirEntry_t      *DirectoryEntry;
-
 
2124
        File_t  file;
-
 
2125
 
-
 
2126
        file.FirstSectorOfCurrCluster   = findelement->fp.FirstSectorOfCurrCluster;
-
 
2127
        file.SectorOfCurrCluster        = findelement->fp.SectorOfCurrCluster;
-
 
2128
        index                                                   = findelement->fp.DirectoryIndex;
-
 
2129
 
-
 
2130
        // within the root directory area we can read sectors sequentially until the end of this area
-
 
2131
        if((Partition.FirstRootDirSector <= file.FirstSectorOfCurrCluster) && (file.FirstSectorOfCurrCluster < Partition.FirstDataSector))
-
 
2132
        {
-
 
2133
                max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
-
 
2134
        }
-
 
2135
        // within the data clusters we can read sectors sequentially only within the cluster
-
 
2136
        else if((Partition.FirstDataSector <= file.FirstSectorOfCurrCluster) && (file.FirstSectorOfCurrCluster <= Partition.LastDataSector))
-
 
2137
        {
-
 
2138
                max_dir_sector = Partition.SectorsPerCluster;                           // limit max secters before next cluster
-
 
2139
        }
-
 
2140
 
-
 
2141
        do
-
 
2142
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
-
 
2143
                if(SD_SUCCESS != SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache));                                             // Read the Rootdirectory.
-
 
2144
                {
-
 
2145
                        Fat16_Deinit();
-
 
2146
                        return(0);
-
 
2147
                }
-
 
2148
               
-
 
2149
                DirectoryEntry = (DirEntry_t *)file.Cache;
-
 
2150
 
-
 
2151
                while((!retvalue)&&(index<16) && (SD_WatchDog))
-
 
2152
                {
-
 
2153
                        i=0;                   
-
 
2154
                        if((u8) DirectoryEntry[index].Name[0] != 0xe5)                                                          // ignore deleted items.
-
 
2155
                        {
-
 
2156
                                while((i<=10)&&((DirectoryEntry[index].Name[i] == findelement->searchstring[i]) || (findelement->searchstring[i]=='*') || findelement->searchstring[i]=='?'))
-
 
2157
                                {
-
 
2158
                                        i++;
-
 
2159
                                }
-
 
2160
                        }
-
 
2161
                        if((DirectoryEntry[index].Attribute <= 0x30) && (DirectoryEntry[index].Attribute & findelement->attribmask) && (i==11))
-
 
2162
                        {
-
 
2163
                for(readpointer=0;readpointer<=10;readpointer++)
-
 
2164
                                {
-
 
2165
                                        if((DirectoryEntry[index].Name[readpointer] != ' ') && (readpointer!=8))
-
 
2166
                                        {
-
 
2167
                                                findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2168
                                                writepointer++;
-
 
2169
                                        }
-
 
2170
                                        else  
-
 
2171
                                        {
-
 
2172
                                                if(DirectoryEntry[index].Attribute == ATTR_ARCHIVE)                                            
-
 
2173
                                                {
-
 
2174
                                        if(readpointer < 8) readpointer=8;
-
 
2175
                                        if(DirectoryEntry[index].Name[readpointer] != ' ')
-
 
2176
                                        {
-
 
2177
                                        findelement->name[writepointer] = '.';                                                  // then seperate the name and the extension by a '.' at index 8.                                                
-
 
2178
                                        writepointer++;
-
 
2179
                                        findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2180
                                        writepointer++;
-
 
2181
                                        }
-
 
2182
                                            else break;
-
 
2183
                                                }
-
 
2184
                            else break;
-
 
2185
                        }
-
 
2186
                        /* terminate the namestring with 0 for debugpurposes*/
-
 
2187
                        findelement->name[12] = 0;
-
 
2188
                                }
-
 
2189
                                findelement->fp.FirstSectorOfFirstCluster = (u32) DirectoryEntry[index].StartCluster;                                                  
-
 
2190
                                findelement->fp.DirectoryIndex   = index;              
-
 
2191
                                findelement->fp.FirstSectorOfCurrCluster   = file.FirstSectorOfCurrCluster;
-
 
2192
                                findelement->fp.DirectorySector  = (file.FirstSectorOfCurrCluster + file.SectorOfCurrCluster);
-
 
2193
                                findelement->fp.SectorOfCurrCluster      = file.SectorOfCurrCluster;
-
 
2194
                findelement->fp.Size            = DirectoryEntry[index].Size;
-
 
2195
                                findelement->fp.Attribute               = DirectoryEntry[index].Attribute;
-
 
2196
                retvalue = 1;
-
 
2197
                        }                      
-
 
2198
                        /* search the next sector */
-
 
2199
                        index++;
-
 
2200
                }
-
 
2201
                /* this sector has been searched but we havn't found what we are looking for. Therefore we have to find the next sector */
-
 
2202
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
-
 
2203
                {
-
 
2204
                        /* in the next sector we start looking for the specified entry beginning at index 0 */
-
 
2205
                        index = 0;
-
 
2206
                        /* there are still sectors to be read within the cluster or within the linear addresspace of the rootdirectory */
-
 
2207
                        if(file.SectorOfCurrCluster < max_dir_sector-1)  file.SectorOfCurrCluster++; else end_of_directory_not_reached = 0;
-
 
2208
                        /* if we are looking for an directoryentry outside the rootdirectory and have reached the end of the cluster we have to get the next one */
-
 
2209
                        if(Partition.FirstDataSector <= file.FirstSectorOfCurrCluster)
-
 
2210
                        {
-
 
2211
                                end_of_directory_not_reached = GetNextCluster(&file);
-
 
2212
                        }
-
 
2213
                }
-
 
2214
        }
-
 
2215
        while((end_of_directory_not_reached) && (!retvalue)  && (SD_WatchDog));
-
 
2216
 
-
 
2217
        return(retvalue);      
-
 
2218
}
-
 
2219
 
-
 
2220
 
-
 
2221
 
-
 
2222
 
-
 
2223
/********************************************************************************************************************************************/
-
 
2224
/*      Function:               findnext_(Find_t *);                                                                                                                                                                                                                    */
-
 
2225
/*                                                                                                                                                                                                                                                                                      */
-
 
2226
/*      Description:    This function looks for the next item in the specified directory with a matching filename and fileattributes specified  */
-
 
2227
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2228
/*                                                                                                                                                                                                                                                                                      */
-
 
2229
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2230
/********************************************************************************************************************************************/
-
 
2231
u8 findnext_(Find_t * findelement)
-
 
2232
{
-
 
2233
        u8 itemfound = 0;
-
 
2234
        u8 index = 0;
-
 
2235
 
-
 
2236
        findelement->fp.DirectoryIndex++;
-
 
2237
 
-
 
2238
        /* before we start searching an element we clear the complete namestring within the structure FindElement */
-
 
2239
        for(index=0;index<11;index++) findelement->name[index] = 0;
-
 
2240
 
-
 
2241
        if(FindItem(findelement))
-
 
2242
        {
-
 
2243
                itemfound = 1;         
-
 
2244
        }
-
 
2245
 
-
 
2246
        return(itemfound);
-
 
2247
}
-
 
2248
 
-
 
2249
 
-
 
2250
 
-
 
2251
/********************************************************************************************************************************************/
-
 
2252
/*      Function:               findfirst_(s8* filename, u8 attribmask, Find_t *);                                                                                                                                              */
-
 
2253
/*                                                                                                                                                                                                                                                                                      */
-
 
2254
/*      Description:    This function looks for the first item in the specified directory with a matching filename and fileattributes                   */
-
 
2255
/*                                      The filename of the element found is transformed from 8.3 to a string                                                                                                   */
-
 
2256
/*                                                                                                                                                                                                                                                                                      */
-
 
2257
/*                                                                                                                                                                                                                                                                                      */
-
 
2258
/*      Returnvalue:    (1) if Element was found. (0) if no valid element was found                                                                                                                     */
-
 
2259
/********************************************************************************************************************************************/
-
 
2260
u8 findfirst_(const s8* name, u8 attribmask, Find_t *findelement)
-
 
2261
{
-
 
2262
        u8 itemfound = 0;
-
 
2263
        u8 index = 0;  
-
 
2264
 
-
 
2265
        /* initialize the FindElement structure */
-
 
2266
        findelement->fp.FirstSectorOfFirstCluster = 0;  // First sector of the first cluster of the file.
-
 
2267
        findelement->fp.FirstSectorOfCurrCluster = Partition.CurrentWorkingDirectory;                                   // First sector of the cluster which is edited at the moment.
-
 
2268
        findelement->fp.SectorOfCurrCluster = 0;                                                        // The sector within the current cluster.
-
 
2269
        findelement->fp.ByteOfCurrSector = 0;                                                   // The byte location within the current sector.
-
 
2270
        findelement->fp.Size = 0;                                                                               // The size of the opend file in bytes.
-
 
2271
        findelement->fp.Position = 0;                                                                   // Pointer to a character within the file 0 < fileposition < filesize
-
 
2272
        findelement->fp.DirectorySector = 0;                                                            // the sectorposition where the directoryentry has been made.
-
 
2273
        findelement->fp.DirectoryIndex = 0;                                                             // The index to the directoryentry within the specified sector.
-
 
2274
        findelement->attribfilter = 0;
-
 
2275
        findelement->attribmask = attribmask;
-
 
2276
        findelement->searchstring[0]=0;
-
 
2277
 
-
 
2278
        /* seperate the name of the element to be found from the filepath and bring it to the 8.3*/
-
 
2279
        SeperateDirName(name, findelement->searchstring);
-
 
2280
        /* after the name of the element is in 8.3 we process the wildcards (*). After an * all following character are wildcards to */
-
 
2281
        for(index=0;index<8;index++)
-
 
2282
        {
-
 
2283
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2284
                if(findelement->searchstring[index] == '*')
-
 
2285
                {
-
 
2286
                        /*  */
-
 
2287
                        while(++index <8) findelement->searchstring[index] = '*';
-
 
2288
                }
-
 
2289
        }
-
 
2290
        for(index=8;index<11;index++)
-
 
2291
        {                                                                                                                                                                                                                                        
-
 
2292
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2293
                if(findelement->searchstring[index] == '*')
-
 
2294
                {
-
 
2295
                        /*  */
-
 
2296
                        while(++index <11) findelement->searchstring[index] = '*';
-
 
2297
                }
-
 
2298
        }
-
 
2299
       
-
 
2300
        /* the value of ...DirectoryIndex will be incremented in findnext_() thererfore it has to be decremented in findfirst_() */
-
 
2301
        findelement->fp.DirectoryIndex--;
-
 
2302
        /* now lets search for the item within the direcory */
-
 
2303
        itemfound = findnext_(findelement);
-
 
2304
 
-
 
2305
        return(itemfound);
-
 
2306
}
-
 
2307
 
-
 
2308
 
-
 
2309
/********************************************************************************************************************************************/
-
 
2310
/*      Function:               u8 GetDirCount(s8* filepath);                                                                                                                                                                                   */
-
 
2311
/*                                                                                                                                                                                                                                                                                      */
-
 
2312
/*      Description:    This function counts the number of subdirectories the dirpath contains                                                                                                  */
-
 
2313
/*                                                                                                                                                                                                                                                              */
-
 
2314
/*                                                                                                                                                                                                                                                                                      */
-
 
2315
/*      Returnvalue:    then number of subdirectories within the specified path                                                                                                                                 */
-
 
2316
/********************************************************************************************************************************************/
-
 
2317
u8 GetDirCount(u8 *dirpath)
-
 
2318
{
-
 
2319
   u8 i=0;
-
 
2320
   u8 cnt=0;
-
 
2321
 
-
 
2322
   while(dirpath[i] != 0  && (SD_WatchDog))
-
 
2323
   {
-
 
2324
      if(dirpath[i]=='/')
-
 
2325
      {  
-
 
2326
         if(dirpath[i+1]!=0) cnt++;                                            // ignore last'/'
-
 
2327
      }
-
 
2328
      i++;  
-
 
2329
   }
-
 
2330
   i=0;  
-
 
2331
   return(cnt);
-
 
2332
}
-
 
2333
 
-
 
2334
 
-
 
2335
/********************************************************************************************************************************************/
-
 
2336
/* Funtion:     char *GetSubDirectory (char *dirpath, char *directory)                                                                                                                                          */
-
 
2337
/*                                                                                                                                                                                                                                                                                      */
-
 
2338
/* Description: this function returns a pointer to the beginning of the next subdirectory or NULL                                                                                       */
-
 
2339
/*                                                                                                                                                                                                                                                                                      */
-
 
2340
/*                                                                                                                                                                                                                                                                                      */
-
 
2341
/* returnvalue:   number of subdirectories in the filepath                                                                                                                                                                      */
-
 
2342
/********************************************************************************************************************************************/
-
 
2343
u8 * GetSubDirectory(u8 *dirpath, u8 *directory)
-
 
2344
{
-
 
2345
   u8 *cptr = dirpath;
-
 
2346
   u8 *dptr = directory;
-
 
2347
   u8 *retvalue = NULL;
-
 
2348
       
-
 
2349
   /* if the first character of the path is an '/' we go to the next character */
-
 
2350
   if(*cptr == '/') cptr++;
-
 
2351
   /* search end of path or subdirectory*/
-
 
2352
   while((*cptr != 0) && (*cptr != '/') && (SD_WatchDog))
-
 
2353
   {
-
 
2354
      *dptr = *cptr;
-
 
2355
       dptr++;
-
 
2356
       cptr++;
-
 
2357
   }  
-
 
2358
   if(*cptr!=0) retvalue = ++cptr;
-
 
2359
   *dptr = 0;
-
 
2360
 
-
 
2361
   return(retvalue);
-
 
2362
}
-
 
2363
 
-
 
2364
/********************************************************************************************************************************************/
-
 
2365
/*      Function:               s8 *GetPath(void);                                                                                                                                                                                                              */
-
 
2366
/*                                                                                                                                                                                                                                                                                      */
-
 
2367
/*      Description:    This function function returns a pointer to the absolute path of the active partition                                                                   */
-
 
2368
/*                                                                                                                                                                                                                                      */
-
 
2369
/*                                                                                                                                                                                                                                                                                      */
-
 
2370
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2371
/********************************************************************************************************************************************/
-
 
2372
 
-
 
2373
s8 *GetPath(void)
-
 
2374
{
-
 
2375
        return(Partition.PathToCwd);
-
 
2376
}
-
 
2377
 
-
 
2378
/********************************************************************************************************************************************/
-
 
2379
/*      Function:               void SetPathToRoot(void);                                                                                                                                                                                                       */
-
 
2380
/*                                                                                                                                                                                                                                                                                      */
-
 
2381
/*      Description:    This function sets the path to the rootdirectory                                                                                                                                                */
-
 
2382
/*                                                                                                                                                                                                                                      */
-
 
2383
/*                                                                                                                                                                                                                                                                                      */
-
 
2384
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2385
/********************************************************************************************************************************************/
-
 
2386
 
-
 
2387
void SetPathToRoot(void)
-
 
2388
{
-
 
2389
        /* lets point to the rootdirectory */
-
 
2390
        strcpy(Partition.PathToCwd, "/");      
-
 
2391
}
-
 
2392
 
-
 
2393
/********************************************************************************************************************************************/
-
 
2394
/*      Function:               void AppendDirToPath(s8* directory);                                                                                                                                                                                    */
-
 
2395
/*                                                                                                                                                                                                                                                                                      */
-
 
2396
/*      Description:    This function function appends the name of an directory to the Path to the CWD                                                                                  */
-
 
2397
/*                                                                                                                                                                                                                                      */
-
 
2398
/*                                                                                                                                                                                                                                                                                      */
-
 
2399
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2400
/********************************************************************************************************************************************/
-
 
2401
 
-
 
2402
void AppendDirToPath(s8* directory)
-
 
2403
{
-
 
2404
        /* append the name of the directory to the path */
-
 
2405
        strcat(Partition.PathToCwd, directory);
-
 
2406
        /* append a '/' after the directoryname */
-
 
2407
        strcat(Partition.PathToCwd, "/");
-
 
2408
}
-
 
2409
 
-
 
2410
/********************************************************************************************************************************************/
-
 
2411
/*      Function:               RemoveLastDirFromPath(void);                                                                                                                                                                                    */
-
 
2412
/*                                                                                                                                                                                                                                                                                      */
-
 
2413
/*      Description:    This function removes the last directory from the path to the cwd                                                                                                               */
-
 
2414
/*                                                                                                                                                                                                                                      */
-
 
2415
/*                                                                                                                                                                                                                                                                                      */
-
 
2416
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2417
/********************************************************************************************************************************************/
-
 
2418
 
-
 
2419
void RemoveLastDirFromPath(void)
-
 
2420
{
-
 
2421
        /* a pointer to the beginning of the absolute path to the cwd */
-
 
2422
        s8 * cptr = Partition.PathToCwd;
-
 
2423
        /* lets find the end of the path to the cwd */
-
 
2424
        while(*cptr != 0  && (SD_WatchDog)) cptr++;
-
 
2425
        /* if the path is terminated with an '/' */
-
 
2426
        if((*(cptr-1)) == '/') *(cptr-1)=0;    
-
 
2427
        /* now lets find the beginning of the last directorientry */
-
 
2428
        while((*cptr != '/'  && (SD_WatchDog)) && cptr > Partition.PathToCwd) cptr--;
-
 
2429
        /* is there one subdirectory left within the path? */
-
 
2430
        if(cptr > Partition.PathToCwd)
-
 
2431
        {
-
 
2432
                /* we delete the direntry by terminating the path with 0 */
-
 
2433
                *cptr = 0;
-
 
2434
        }
-
 
2435
        /* there is no subdirectory left within the path. Therefore we create the root instead. */
-
 
2436
        else
-
 
2437
        {
-
 
2438
                *cptr = '/';
-
 
2439
                *(cptr+1) = 0;
-
 
2440
        }
-
 
2441
}
-
 
2442
 
-
 
2443
/********************************************************************************************************************************************/
-
 
2444
/*      Function:               chdir_(s8* filepath);                                                                                                                                                                                                   */
-
 
2445
/*                                                                                                                                                                                                                                                                                      */
-
 
2446
/*      Description:    This function changed the current working directory to the directory specified by the filepath                                                  */
-
 
2447
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2448
/*                                                                                                                                                                                                                                                                                      */
-
 
2449
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2450
/********************************************************************************************************************************************/
-
 
2451
/*                                                                         
-
 
2452
#define ATTR_NONE               0x00    // normal file
-
 
2453
#define ATTR_READONLY           0x01    // file is readonly
-
 
2454
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2455
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2456
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2457
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2458
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2459
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2460
*/
-
 
2461
 
-
 
2462
u8 chdir_(s8 *path)
-
 
2463
{
-
 
2464
        u8              retvalue = 0;                                   // the value returned by this function
-
 
2465
        u32     ultemp = 0;                                             // temp. variable
-
 
2466
        u8     *directory = path;                               // pointer to a directoryname within the path
-
 
2467
        u8      dircount = 0;                                   // the number of subdirectoryentries within the path
-
 
2468
        u8      cache[64];                                              // a buffer containing the name of the subdirectory we are actually looking for
-
 
2469
        Find_t  fe;                                                             // The findelement needed for function findfirst to find the subdirectoryentry
-
 
2470
        s8              tp[256];                                                // temporarily we remember the actual path until the operation has finished successfully
-
 
2471
        u32     cwdt = 0;
-
 
2472
        s8     *cptr;
-
 
2473
 
-
 
2474
        /* bring the path into the correct syntax */
-
 
2475
        cptr = path;
-
 
2476
        /* search the whole string */
-
 
2477
        while(*cptr != 0  && (SD_WatchDog))
-
 
2478
        {
-
 
2479
                if(*cptr == '\\') *cptr = '/';
-
 
2480
                cptr++;
-
 
2481
        }
-
 
2482
        /* lets remember the actual path */
-
 
2483
        strcpy(tp, Partition.PathToCwd);
-
 
2484
        cwdt = Partition.CurrentWorkingDirectory;
-
 
2485
        /* how many subdirectories are there within the path? */
-
 
2486
        dircount = GetDirCount(path);  
-
 
2487
        /* if the path is absolute we begin at the rootdirectory */
-
 
2488
        if(path[0] == '/')
-
 
2489
        {
-
 
2490
                strcpy(Partition.PathToCwd, "/");
-
 
2491
                Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
2492
                /* if there is no other pathinformation we only switch to the rootdirectory. So theres nothing left todo.*/
-
 
2493
                if(!dircount) return(1);
-
 
2494
        }
-
 
2495
        /* now we parse through all the subdirectories within the path */
-
 
2496
        do
-
 
2497
        {  
-
 
2498
                /* until all the subdirectories within the path have been processed */
-
 
2499
        if(dircount) dircount--;
-
 
2500
                /* this is the name of the next subdirectory we are looking for */             
-
 
2501
            directory = GetSubDirectory(directory, cache);  
-
 
2502
                /* search for the next subdirectory within the path */
-
 
2503
                if(findfirst_(cache, ATTR_SUBDIRECTORY, &fe))
-
 
2504
                {
-
 
2505
                        /* we try to change into the directory "..". Now we have to delete the last direntry from the path */
-
 
2506
                        if(strcmp(cache,"..") == 0) RemoveLastDirFromPath();
-
 
2507
                        /* we try to change into the actual directory so there's nothing todo */
-
 
2508
                        else if(cache[0] == '.') return(1);
-
 
2509
                        /* otherwise we append the name of the directory we are changing in to the path */
-
 
2510
                        else AppendDirToPath(cache);
-
 
2511
                        /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */
-
 
2512
                        ultemp = (u32) fe.fp.FirstSectorOfFirstCluster;
-
 
2513
                        /* the first 2 entries are reserved for '.' and '..' */
-
 
2514
                        ultemp -= 2;
-
 
2515
                        /* now we have to transform the position within the fat into the corrosponding sectoraddress relative to the beginning of the datasection of the active partition*/
-
 
2516
                        ultemp *= Partition.SectorsPerCluster;
-
 
2517
                        /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */
-
 
2518
                        ultemp += Partition.FirstDataSector;
-
 
2519
                        /* the cwd now points to the specified directory */
-
 
2520
                        Partition.CurrentWorkingDirectory = ultemp;
-
 
2521
                        /* we found the folder specified by the foldername */
-
 
2522
                        retvalue = 1;
-
 
2523
                }
-
 
2524
        }
-
 
2525
        /* do this until all subdirectories have been found or a subdirectory is missing */
-
 
2526
        while(dircount && retvalue  && (SD_WatchDog));
-
 
2527
 
-
 
2528
        /* if we could not change to the specified directory we restore the actual path */
-
 
2529
        if(!retvalue)
-
 
2530
        {
-
 
2531
                Partition.CurrentWorkingDirectory = cwdt;                                                  
-
 
2532
                strcpy(Partition.PathToCwd, tp);
-
 
2533
        }
-
 
2534
        return(retvalue);      
-