Subversion Repositories NaviCtrl

Rev

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

Rev 324 Rev 349
Line 53... Line 53...
53
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53
// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55
// +  POSSIBILITY OF SUCH DAMAGE.
55
// +  POSSIBILITY OF SUCH DAMAGE.
56
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57
#include <stdio.h>
57
#include <stdio.h>
-
 
58
#include <string.h>
58
#include "91x_lib.h"
59
#include "91x_lib.h"
59
#include "timer1.h"
60
#include "timer1.h"
60
#include "fat16.h"
61
#include "fat16.h"
61
#include "sdc.h"
62
#include "sdc.h"
62
#include "uart1.h"
63
#include "uart1.h"
Line -... Line 64...
-
 
64
 
63
 
65
void Test(void);
64
//________________________________________________________________________________________________________________________________________
66
//________________________________________________________________________________________________________________________________________
65
// Module name:                 fat16.c
67
// Module name:                 fat16.c
66
// Compiler used:               avr-gcc 3.4.5
68
// Compiler used:               avr-gcc 3.4.5
67
// Last Modifikation:   20.03.2010
69
// Last Modifikation:   20.03.2010
Line 124... Line 126...
124
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
126
        u16     EndCylSec;                                      // End of Partition - Cylinder/Sector
125
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
127
        u32     NoSectorsBeforePartition;       // Number of Sectors between the MBR and the First Sector in the Partition
126
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
128
        u32     NoSectorsPartition      ;               // Number of Sectors in the Partition
127
} __attribute__((packed)) PartitionEntry_t;
129
} __attribute__((packed)) PartitionEntry_t;
Line -... Line 130...
-
 
130
 
-
 
131
 
128
 
132
 
129
/*
133
/*
Line 130... Line 134...
130
Coding of Cylinder/Sector words
134
Coding of Cylinder/Sector words
131
 
135
 
Line 307... Line 311...
307
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
311
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
308
        u32 FirstFatSector;                     // sector of the start of the fat
312
        u32 FirstFatSector;                     // sector of the start of the fat
309
        u32 FirstRootDirSector;         // sector of the rootdirectory
313
        u32 FirstRootDirSector;         // sector of the rootdirectory
310
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
314
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
311
        u32 LastDataSector;                     // the last data sector of the partition
315
        u32 LastDataSector;                     // the last data sector of the partition
312
        u8 VolumeLabel[12];                     // the volume label
316
        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                               
313
} Partition_t;
319
}   __attribute__((packed)) Partition_t;
Line 314... Line 320...
314
 
320
 
Line 315... Line 321...
315
Partition_t     Partition;                                      // Structure holds partition information
321
Partition_t     Partition;              // Structure holds partition information
Line 316... Line 322...
316
 
322
 
Line 569... Line 575...
569
        File_t *file;
575
        File_t *file;
570
        u8 result = 0;
576
        u8 result = 0;
Line 571... Line 577...
571
 
577
 
572
        UART1_PutString("\r\n FAT16 init...");
578
        UART1_PutString("\r\n FAT16 init...");
573
        Partition.IsValid = 0;
-
 
574
 
579
        Partition.IsValid = 0;
575
        // declare the filepointers as unused.
580
        // declare the filepointers as unused.
576
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
581
        for(cnt = 0; cnt < FILE_MAX_OPEN; cnt++)
577
        {
582
        {
578
                UnlockFilePointer(&FilePointer[cnt]);
583
                UnlockFilePointer(&FilePointer[cnt]);
Line 652... Line 657...
652
                UART1_PutString("VBR: Partition ist not FAT16 type.");
657
                UART1_PutString("VBR: Partition ist not FAT16 type.");
653
                result = 6;
658
                result = 6;
654
                goto end;
659
                goto end;
655
        }
660
        }
656
        Partition.IsValid = 1; // mark data in partition structure as valid
661
        Partition.IsValid = 1; // mark data in partition structure as valid
-
 
662
        Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector;
-
 
663
        strcpy(Partition.PathToCwd,"/");
657
        result = 0;
664
        result = 0;
-
 
665
 
-
 
666
//      Test();
658
        end:
667
        end:
659
        if(result != 0) Fat16_Deinit();
668
        if(result != 0) Fat16_Deinit();
660
        else UART1_PutString("ok");
669
        else UART1_PutString("ok");
661
        return(result);
670
        return(result);
662
}
671
}
Line 1035... Line 1044...
1035
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
1044
        if((!Partition.IsValid) || (file == NULL) || (dirname == NULL)) return(direntry_exist);
Line 1036... Line 1045...
1036
 
1045
 
1037
        // dir entries can be searched only in filesclusters that have
1046
        // dir entries can be searched only in filesclusters that have
1038
        // a corresponding dir entry with adir-flag set in its attribute
1047
        // a corresponding dir entry with adir-flag set in its attribute
1039
        // or direct within the root directory area
-
 
1040
 
1048
        // or direct within the root directory area
1041
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1049
        file->FirstSectorOfFirstCluster = SECTOR_UNDEFINED;
1042
        // no current directory exist therefore assume searching in the root
1050
        // no current directory exist therefore assume searching in the root
1043
        if(file->DirectorySector == SECTOR_UNDEFINED)
1051
        if(file->DirectorySector == SECTOR_UNDEFINED)
1044
        {
1052
        {
Line 1090... Line 1098...
1090
        file->SectorOfCurrCluster               = 0;
1098
        file->SectorOfCurrCluster               = 0;
1091
        file->ByteOfCurrSector                  = 0;
1099
        file->ByteOfCurrSector                  = 0;
Line 1092... Line 1100...
1092
 
1100
 
1093
        do // loop over all data clusters of the current directory entry
1101
        do // loop over all data clusters of the current directory entry
1094
        {
1102
        {
1095
                dir_sector = 0; // reset sector counter within a new cluster
1103
                dir_sector = 0;
1096
                do // loop over all sectors of a cluster or all sectors of the root directory
1104
                do // loop over all sectors of a cluster or all sectors of the root directory
1097
                {
1105
                {
1098
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1106
                        curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
1099
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
1107
                        file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
Line 1348... Line 1356...
1348
 
1356
 
1349
        // trace along the filepath
1357
        // trace along the filepath
1350
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1358
        path = (s8*)filename;                                                           // start a the beginning of the filename string
1351
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
1359
        file->DirectorySector = 0;                                                              // start at RootDirectory with file search
-
 
1360
        file->DirectoryIndex = 0;
-
 
1361
        /* if a path begins with a '/' at index 0 the search starts at the rootdirectory otherwise we will start relative to the cwd */
-
 
1362
        if(path[0] != '/')
-
 
1363
        {
-
 
1364
                /* is the current working directory the rootdirectory? */
-
 
1365
                if(Partition.CurrentWorkingDirectory == Partition.FirstRootDirSector) file->DirectorySector = 0;
-
 
1366
                /* otherwise we are working in an subdirectory */
-
 
1367
                else file->DirectorySector = Partition.CurrentWorkingDirectory;
1352
        file->DirectoryIndex = 0;
1368
        }
1353
        // as long as the file was not found and the remaining path is not empty
1369
        // as long as the file was not found and the remaining path is not empty
1354
        while((*path != 0) && !file_exist)
1370
        while((*path != 0) && !file_exist)
1355
        {       // separate dirname and subpath from filepath string
1371
        {       // separate dirname and subpath from filepath string
1356
                subpath = SeperateDirName(path, dirname);
1372
                subpath = SeperateDirName(path, dirname);
Line 1557... Line 1573...
1557
                                // try to create the file
1573
                                // try to create the file
1558
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1574
                                if(!FileCreate(filename, ATTR_ARCHIVE, file))
1559
                                { // if it could not be created
1575
                                { // if it could not be created
1560
                                        fclose_(file);
1576
                                        fclose_(file);
1561
                                        file = NULL;
1577
                                        file = NULL;
1562
                                }
1578
                                }
1563
                                break;
1579
                                break;
1564
                        case 'r': // else opened for 'r'
1580
                        case 'r': // else opened for 'r'
1565
                        default:  // if unsupported mode
1581
                        default:  // if unsupported mode
1566
                                fclose_(file);
1582
                                fclose_(file);
1567
                                file = NULL;
1583
                                file = NULL;
Line 1660... Line 1676...
1660
        s16 c = EOF;
1676
        s16 c = EOF;
1661
        u32 curr_sector;
1677
        u32 curr_sector;
Line 1662... Line 1678...
1662
 
1678
 
1663
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1679
        if( (!Partition.IsValid) || (file == NULL)) return(c);
1664
        // if the end of the file is not reached, get the next character.
1680
        // if the end of the file is not reached, get the next character.
1665
        if((0 < file->Size) && ((file->Position+1) < file->Size) )
1681
        if((0 < file->Size) && ((file->Position) < file->Size) )
1666
        {
1682
        {
1667
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
1683
                curr_sector  = file->FirstSectorOfCurrCluster;          // calculate the sector of the next character to be read.
Line 1668... Line 1684...
1668
                curr_sector += file->SectorOfCurrCluster;
1684
                curr_sector += file->SectorOfCurrCluster;
Line 2039... Line 2055...
2039
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
2055
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
Line 2040... Line 2056...
2040
 
2056
 
2041
        UnlockFilePointer(file);
2057
        UnlockFilePointer(file);
2042
        return(pVolumeLabel);
2058
        return(pVolumeLabel);
-
 
2059
}
-
 
2060
 
-
 
2061
 
-
 
2062
 
-
 
2063
#define ATTR_NONE               0x00    // normal file
-
 
2064
#define ATTR_READONLY           0x01    // file is readonly
-
 
2065
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2066
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2067
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2068
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2069
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2070
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2071
 
-
 
2072
 
-
 
2073
/********************************************************************************************************************************************/
-
 
2074
/*      Function:               u8 FindItem(Find_t);                                                                                                                                                                                                                    */
-
 
2075
/*                                                                                                                                                                                                                                                                                      */
-
 
2076
/*      Description:    This function looks for the item specified by global structure FindElement in the actual directory                                      */
-
 
2077
/*                                                                                                                                                                                                                                                              */
-
 
2078
/*                                                                                                                                                                                                                                                                                      */
-
 
2079
/*      Returnvalue:    TRUE if an matching element was found                                                                                                                                                                           */
-
 
2080
/********************************************************************************************************************************************/
-
 
2081
 
-
 
2082
u8 FindItem(Find_t *findelement)
-
 
2083
{
-
 
2084
        u16     index = 0;
-
 
2085
        u16   end_of_directory_not_reached = 1;                                                                         // the directory has been read completely without a result.
-
 
2086
        u8      i = 0;
-
 
2087
        u8              readpointer = 0;
-
 
2088
        u8              writepointer = 0;
-
 
2089
        u8              retvalue = 0;
-
 
2090
        DirEntry_t      *DirectoryEntry;
-
 
2091
        File_t  file;
-
 
2092
 
-
 
2093
        file.FirstSectorOfCurrCluster   = findelement->fp.FirstSectorOfCurrCluster;
-
 
2094
        file.SectorOfCurrCluster        = findelement->fp.SectorOfCurrCluster;
-
 
2095
        index                                                   = findelement->fp.DirectoryIndex;
-
 
2096
 
-
 
2097
 
-
 
2098
        do
-
 
2099
        {                                                                                                                                                               // search the next 16 rootentries in this sector of the roordirectory.          
-
 
2100
                SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache);                                               // Read the Rootdirectory.
-
 
2101
                DirectoryEntry = (DirEntry_t *)file.Cache;
-
 
2102
 
-
 
2103
                while((!retvalue)&&(index<16))
-
 
2104
                {
-
 
2105
                        i=0;                   
-
 
2106
                        if((u8) DirectoryEntry[index].Name[0] != 0xe5)                                                          // ignore deleted items.
-
 
2107
                        {
-
 
2108
                                while((i<=10)&&((DirectoryEntry[index].Name[i] == findelement->searchstring[i]) || (findelement->searchstring[i]=='*') || findelement->searchstring[i]=='?'))
-
 
2109
                                {
-
 
2110
                                        i++;
-
 
2111
                                }
-
 
2112
                        }
-
 
2113
                        if((DirectoryEntry[index].Attribute <= 0x30) && (DirectoryEntry[index].Attribute & findelement->attribmask) && (i==11))
-
 
2114
                        {
-
 
2115
                for(readpointer=0;readpointer<=10;readpointer++)
-
 
2116
                                {
-
 
2117
                                        if((DirectoryEntry[index].Name[readpointer] != ' ') && (readpointer!=8))
-
 
2118
                                        {
-
 
2119
                                                findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2120
                                                writepointer++;
-
 
2121
                                        }
-
 
2122
                                        else  
-
 
2123
                                        {
-
 
2124
                                                if(DirectoryEntry[index].Attribute == ATTR_ARCHIVE)
-
 
2125
                                                {
-
 
2126
                                        if(readpointer < 8) readpointer=8;
-
 
2127
                                        if(DirectoryEntry[index].Name[readpointer] != ' ')
-
 
2128
                                        {
-
 
2129
                                        findelement->name[writepointer] = '.';                                                  // then seperate the name and the extension by a '.' at index 8.                                                
-
 
2130
                                        writepointer++;
-
 
2131
                                        findelement->name[writepointer] = DirectoryEntry[index].Name[readpointer];      // copy the name of the item found to the find_structure.
-
 
2132
                                        writepointer++;
-
 
2133
                                        }
-
 
2134
                                            else break;
-
 
2135
                                                }
-
 
2136
                            else break;
-
 
2137
                        }
-
 
2138
                        /* terminate the namestring with 0 for debugpurposes*/
-
 
2139
                        findelement->name[12] = 0;
-
 
2140
                                }
-
 
2141
                                findelement->fp.FirstSectorOfFirstCluster = (u32) DirectoryEntry[index].StartCluster;                                                  
-
 
2142
                                findelement->fp.DirectoryIndex   = index;              
-
 
2143
                                findelement->fp.FirstSectorOfCurrCluster   = file.FirstSectorOfCurrCluster;
-
 
2144
                                findelement->fp.DirectorySector  = (file.FirstSectorOfCurrCluster + file.SectorOfCurrCluster);
-
 
2145
                                findelement->fp.SectorOfCurrCluster      = file.SectorOfCurrCluster;
-
 
2146
                findelement->fp.Size            = DirectoryEntry[index].Size;
-
 
2147
                                findelement->fp.Attribute               = DirectoryEntry[index].Attribute;
-
 
2148
                retvalue = 1;
-
 
2149
                        }                      
-
 
2150
                        index++;
-
 
2151
                }
-
 
2152
                if(!retvalue)                                                                                                                           // file not found in this sector so take next sector.
-
 
2153
                {
-
 
2154
                file.SectorOfCurrCluster++;                            
-
 
2155
                        if(file.SectorOfCurrCluster >= Partition.SectorsPerCluster)
-
 
2156
                {  
-
 
2157
                                file.SectorOfCurrCluster=0;
-
 
2158
                                end_of_directory_not_reached = GetNextCluster(&file);
-
 
2159
                        }
-
 
2160
                }
-
 
2161
                index = 0;
-
 
2162
        }
-
 
2163
        while((end_of_directory_not_reached) && (!retvalue));
-
 
2164
 
-
 
2165
        return(retvalue);      
-
 
2166
}
-
 
2167
 
-
 
2168
 
-
 
2169
/********************************************************************************************************************************************/
-
 
2170
/*      Function:               findnext_(Find_t *);                                                                                                                                                                                                                    */
-
 
2171
/*                                                                                                                                                                                                                                                                                      */
-
 
2172
/*      Description:    This function looks for the next item in the specified directory with a matching filename and fileattributes specified  */
-
 
2173
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2174
/*                                                                                                                                                                                                                                                                                      */
-
 
2175
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2176
/********************************************************************************************************************************************/
-
 
2177
u8 findnext_(Find_t * findelement)
-
 
2178
{
-
 
2179
        u8 itemfound = 0;
-
 
2180
        u8 index = 0;
-
 
2181
 
-
 
2182
        findelement->fp.DirectoryIndex++;
-
 
2183
 
-
 
2184
        /* before we start searching an element we clear the complete namestring within the structure FindElement */
-
 
2185
        for(index=0;index<11;index++) findelement->name[index] = 0;
-
 
2186
 
-
 
2187
        if(FindItem(findelement))
-
 
2188
        {
-
 
2189
                itemfound = 1;         
-
 
2190
        }
-
 
2191
 
-
 
2192
        return(itemfound);
-
 
2193
}
-
 
2194
 
-
 
2195
 
-
 
2196
 
-
 
2197
/********************************************************************************************************************************************/
-
 
2198
/*      Function:               findfirst_(s8* filename, u8 attribfilter, u8 attribmask, Find_t *);                                                                                                                             */
-
 
2199
/*                                                                                                                                                                                                                                                                                      */
-
 
2200
/*      Description:    This function looks for the first item in the specified directory with a matching filename and fileattributes                   */
-
 
2201
/*                                      The filename of the element found is transformed from 8.3 to a string                                                                                                   */
-
 
2202
/*                                                                                                                                                                                                                                                                                      */
-
 
2203
/*                                                                                                                                                                                                                                                                                      */
-
 
2204
/*      Returnvalue:    (1) if Element was found. (0) if no valid element was found                                                                                                                     */
-
 
2205
/********************************************************************************************************************************************/
-
 
2206
u8 findfirst_(const s8* name, u8 attribmask, Find_t *findelement)
-
 
2207
{
-
 
2208
        u8 itemfound = 0;
-
 
2209
        u8 index = 0;  
-
 
2210
 
-
 
2211
        /* initialize the FindElement structure */
-
 
2212
        findelement->fp.FirstSectorOfFirstCluster = 0;  // First sector of the first cluster of the file.
-
 
2213
        findelement->fp.FirstSectorOfCurrCluster = Partition.CurrentWorkingDirectory;                                   // First sector of the cluster which is edited at the moment.
-
 
2214
        findelement->fp.SectorOfCurrCluster = 0;                                                        // The sector within the current cluster.
-
 
2215
        findelement->fp.ByteOfCurrSector = 0;                                                   // The byte location within the current sector.
-
 
2216
        findelement->fp.Size = 0;                                                                               // The size of the opend file in bytes.
-
 
2217
        findelement->fp.Position = 0;                                                                   // Pointer to a character within the file 0 < fileposition < filesize
-
 
2218
        findelement->fp.DirectorySector = 0;                                                            // the sectorposition where the directoryentry has been made.
-
 
2219
        findelement->fp.DirectoryIndex = 0;                                                             // The index to the directoryentry within the specified sector.
-
 
2220
        findelement->attribfilter = 0;
-
 
2221
        findelement->attribmask = attribmask;
-
 
2222
        findelement->searchstring[0]=0;
-
 
2223
 
-
 
2224
        /* seperate the name of the element to be found from the filepath and bring it to the 8.3*/
-
 
2225
        SeperateDirName(name, findelement->searchstring);
-
 
2226
        /* after the name of the element is in 8.3 we process the wildcards (*). After an * all following character are wildcards to */
-
 
2227
        for(index=0;index<8;index++)
-
 
2228
        {
-
 
2229
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2230
                if(findelement->searchstring[index] == '*')
-
 
2231
                {
-
 
2232
                        /*  */
-
 
2233
                        while(++index <8) findelement->searchstring[index] = '*';
-
 
2234
                }
-
 
2235
        }
-
 
2236
        for(index=8;index<11;index++)
-
 
2237
        {                                                                                                                                                                                                                                        
-
 
2238
                /* if we find an wildcard within the name of the searchstring all remaining character after the wildcard shall be wildcards also */
-
 
2239
                if(findelement->searchstring[index] == '*')
-
 
2240
                {
-
 
2241
                        /*  */
-
 
2242
                        while(++index <11) findelement->searchstring[index] = '*';
-
 
2243
                }
-
 
2244
        }
-
 
2245
       
-
 
2246
        /* the value of ...DirectoryIndex will be incremented in findnext_() thererfore it has to be decremented in findfirst_() */
-
 
2247
        findelement->fp.DirectoryIndex--;
-
 
2248
        /* now lets search for the item within the direcory */
-
 
2249
        itemfound = findnext_(findelement);
-
 
2250
 
-
 
2251
        return(itemfound);
-
 
2252
}
-
 
2253
 
-
 
2254
 
-
 
2255
/********************************************************************************************************************************************/
-
 
2256
/*      Function:               u8 GetDirCount(s8* filepath);                                                                                                                                                                                   */
-
 
2257
/*                                                                                                                                                                                                                                                                                      */
-
 
2258
/*      Description:    This function counts the number of subdirectories the dirpath contains                                                                                                  */
-
 
2259
/*                                                                                                                                                                                                                                                              */
-
 
2260
/*                                                                                                                                                                                                                                                                                      */
-
 
2261
/*      Returnvalue:    then number of subdirectories within the specified path                                                                                                                                 */
-
 
2262
/********************************************************************************************************************************************/
-
 
2263
u8 GetDirCount(u8 *dirpath)
-
 
2264
{
-
 
2265
   u8 i=0;
-
 
2266
   u8 cnt=0;
-
 
2267
 
-
 
2268
   while(dirpath[i] != 0)
-
 
2269
   {
-
 
2270
      if(dirpath[i]=='/')
-
 
2271
      {  
-
 
2272
         if(dirpath[i+1]!=0) cnt++;                                            // ignore last'/'
-
 
2273
      }
-
 
2274
      i++;  
-
 
2275
   }
-
 
2276
   i=0;  
-
 
2277
   return(cnt);
-
 
2278
}
-
 
2279
 
-
 
2280
 
-
 
2281
/********************************************************************************************************************************************/
-
 
2282
/* Funtion:     char *GetSubDirectory (char *dirpath, char *directory)                                                                                                                                          */
-
 
2283
/*                                                                                                                                                                                                                                                                                      */
-
 
2284
/* Description: this function returns a pointer to the beginning of the next subdirectory or NULL                                                                                       */
-
 
2285
/*                                                                                                                                                                                                                                                                                      */
-
 
2286
/*                                                                                                                                                                                                                                                                                      */
-
 
2287
/* returnvalue:   number of subdirectories in the filepath                                                                                                                                                                      */
-
 
2288
/********************************************************************************************************************************************/
-
 
2289
u8 * GetSubDirectory(u8 *dirpath, u8 *directory)
-
 
2290
{
-
 
2291
   u8 *cptr = dirpath;
-
 
2292
   u8 *dptr = directory;
-
 
2293
   u8 *retvalue = NULL;
-
 
2294
       
-
 
2295
   /* if the first character of the path is an '/' we go to the next character */
-
 
2296
   if(*cptr == '/') cptr++;
-
 
2297
   /* search end of path or subdirectory*/
-
 
2298
   while((*cptr != 0) && (*cptr != '/'))
-
 
2299
   {
-
 
2300
      *dptr = *cptr;
-
 
2301
       dptr++;
-
 
2302
       cptr++;
-
 
2303
   }  
-
 
2304
   if(*cptr!=0) retvalue = ++cptr;
-
 
2305
   *dptr = 0;
-
 
2306
 
-
 
2307
   return(retvalue);
-
 
2308
}
-
 
2309
 
-
 
2310
/********************************************************************************************************************************************/
-
 
2311
/*      Function:               s8 *GetPath(void);                                                                                                                                                                                                              */
-
 
2312
/*                                                                                                                                                                                                                                                                                      */
-
 
2313
/*      Description:    This function function returns a pointer to the absolute path of the active partition                                                                   */
-
 
2314
/*                                                                                                                                                                                                                                      */
-
 
2315
/*                                                                                                                                                                                                                                                                                      */
-
 
2316
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2317
/********************************************************************************************************************************************/
-
 
2318
 
-
 
2319
s8 *GetPath(void)
-
 
2320
{
-
 
2321
        return(Partition.PathToCwd);
-
 
2322
}
-
 
2323
 
-
 
2324
/********************************************************************************************************************************************/
-
 
2325
/*      Function:               void SetPathToRoot(void);                                                                                                                                                                                                       */
-
 
2326
/*                                                                                                                                                                                                                                                                                      */
-
 
2327
/*      Description:    This function sets the path to the rootdirectory                                                                                                                                                */
-
 
2328
/*                                                                                                                                                                                                                                      */
-
 
2329
/*                                                                                                                                                                                                                                                                                      */
-
 
2330
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2331
/********************************************************************************************************************************************/
-
 
2332
 
-
 
2333
void SetPathToRoot(void)
-
 
2334
{
-
 
2335
        /* lets point to the rootdirectory */
-
 
2336
        strcpy(Partition.PathToCwd, "/");      
-
 
2337
}
-
 
2338
 
-
 
2339
/********************************************************************************************************************************************/
-
 
2340
/*      Function:               void AppendDirToPath(s8* directory);                                                                                                                                                                                    */
-
 
2341
/*                                                                                                                                                                                                                                                                                      */
-
 
2342
/*      Description:    This function function appends the name of an directory to the Path to the CWD                                                                                  */
-
 
2343
/*                                                                                                                                                                                                                                      */
-
 
2344
/*                                                                                                                                                                                                                                                                                      */
-
 
2345
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2346
/********************************************************************************************************************************************/
-
 
2347
 
-
 
2348
void AppendDirToPath(s8* directory)
-
 
2349
{
-
 
2350
        /* append the name of the directory to the path */
-
 
2351
        strcat(Partition.PathToCwd, directory);
-
 
2352
        /* append a '/' after the directoryname */
-
 
2353
        strcat(Partition.PathToCwd, "/");
-
 
2354
}
-
 
2355
 
-
 
2356
/********************************************************************************************************************************************/
-
 
2357
/*      Function:               RemoveLastDirFromPath(void);                                                                                                                                                                                    */
-
 
2358
/*                                                                                                                                                                                                                                                                                      */
-
 
2359
/*      Description:    This function removes the last directory from the path to the cwd                                                                                                               */
-
 
2360
/*                                                                                                                                                                                                                                      */
-
 
2361
/*                                                                                                                                                                                                                                                                                      */
-
 
2362
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2363
/********************************************************************************************************************************************/
-
 
2364
 
-
 
2365
void RemoveLastDirFromPath(void)
-
 
2366
{
-
 
2367
        /* a pointer to the beginning of the absolute path to the cwd */
-
 
2368
        s8 * cptr = Partition.PathToCwd;
-
 
2369
        /* lets find the end of the path to the cwd */
-
 
2370
        while(*cptr++ != 0);
-
 
2371
        /* now lets find the beginning of the last directorientry */
-
 
2372
        while(*cptr-- != '/');
-
 
2373
        /* we delete the direntry by terminating the path with 0 */
-
 
2374
        *++cptr = 0;
-
 
2375
}
-
 
2376
 
-
 
2377
/********************************************************************************************************************************************/
-
 
2378
/*      Function:               chdir_(s8* filepath);                                                                                                                                                                                                   */
-
 
2379
/*                                                                                                                                                                                                                                                                                      */
-
 
2380
/*      Description:    This function changed the current working directory to the directory specified by the filepath                                                  */
-
 
2381
/*                  by function findfirst()                                                                                                                                                                                                     */
-
 
2382
/*                                                                                                                                                                                                                                                                                      */
-
 
2383
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2384
/********************************************************************************************************************************************/
-
 
2385
/*
-
 
2386
#define ATTR_NONE               0x00    // normal file
-
 
2387
#define ATTR_READONLY           0x01    // file is readonly
-
 
2388
#define ATTR_HIDDEN                     0x02    // file is hidden
-
 
2389
#define ATTR_SYSTEM                     0x04    // file is a system file
-
 
2390
#define ATTR_VOLUMELABEL        0x08    // entry is a volume label
-
 
2391
#define ATTR_LONG_FILENAME      0x0F    // this is a long filename entry
-
 
2392
#define ATTR_SUBDIRECTORY       0x10    // entry is a directory name
-
 
2393
#define ATTR_ARCHIVE            0x20    // file is new or modified
-
 
2394
*/
-
 
2395
 
-
 
2396
u8 chdir_(s8 *path)
-
 
2397
{
-
 
2398
        u8              retvalue = 0;                                   // the value returned by this function
-
 
2399
        u32     ultemp = 0;                                             // temp. variable
-
 
2400
        u8     *directory = path;                               // pointer to a directoryname within the path
-
 
2401
        u8      dircount = 0;                                   // the number of subdirectoryentries within the path
-
 
2402
        u8      cache[64];                                              // a buffer containing the name of the subdirectory we are actually looking for
-
 
2403
        Find_t  fe;                                                             // The findelement needed for function findfirst to find the subdirectoryentry
-
 
2404
        s8              tp[256];                                                // temporarily we remember the actual path until the operation has finished successfully
-
 
2405
        u32     cwdt = 0;
-
 
2406
 
-
 
2407
        /* lets remember the actual path */
-
 
2408
        strcpy(tp, Partition.PathToCwd);
-
 
2409
        cwdt = Partition.CurrentWorkingDirectory;
-
 
2410
        /* if the path is absolute we begin at the rootdirectory */
-
 
2411
        strcpy(Partition.PathToCwd, "/");
-
 
2412
        /* how many subdirectories are there within the path? */
-
 
2413
        dircount = GetDirCount(path);  
-
 
2414
        /* now we parse through all the subdirectories within the path */
-
 
2415
        do
-
 
2416
        {  
-
 
2417
                /* until all the subdirectories within the path have been processed */
-
 
2418
        if(dircount) dircount--;
-
 
2419
                /* this is the name of the next subdirectory we are looking for */             
-
 
2420
            directory = GetSubDirectory(directory, cache);  
-
 
2421
                /* search for the next subdirectory within the path */
-
 
2422
                if(findfirst_(cache, ATTR_SUBDIRECTORY, &fe))
-
 
2423
                {
-
 
2424
                        /* we try to change into the directory "..". Now we have to delete the last direntry from the path */
-
 
2425
                        if(strcmp(cache,"..") == 0) RemoveLastDirFromPath();
-
 
2426
                        /* we try to change into the actual directory so there's nothing todo */
-
 
2427
                        else if(cache[0] == '.') return(1);
-
 
2428
                        /* otherwise we append the name of the directory we are changing in to the path */
-
 
2429
                        else AppendDirToPath(cache);
-
 
2430
                        /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */
-
 
2431
                        ultemp = (u32) fe.fp.FirstSectorOfFirstCluster;
-
 
2432
                        /* the first 2 entries are reserved for '.' and '..' */
-
 
2433
                        ultemp -= 2;
-
 
2434
                        /* 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*/
-
 
2435
                        ultemp *= Partition.SectorsPerCluster;
-
 
2436
                        /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */
-
 
2437
                        ultemp += Partition.FirstDataSector;
-
 
2438
                        /* the cwd now points to the specified directory */
-
 
2439
                        Partition.CurrentWorkingDirectory = ultemp;
-
 
2440
                        /* we found the folder specified by the foldername */
-
 
2441
                        retvalue = 1;
-
 
2442
                }
-
 
2443
        }
-
 
2444
        /* do this until all subdirectories have been found or a subdirectory is missing */
-
 
2445
        while(dircount && retvalue);
-
 
2446
 
-
 
2447
        /* if we could not change to the specified directory we restore the actual path */
-
 
2448
        if(!retvalue)
-
 
2449
        {
-
 
2450
                Partition.CurrentWorkingDirectory = cwdt;
-
 
2451
                strcpy(Partition.PathToCwd, tp);
-
 
2452
        }
-
 
2453
        return(retvalue);      
-
 
2454
}
-
 
2455
 
-
 
2456
/********************************************************************************************************************************************/
-
 
2457
/*      Function:               void Test(void);                                                                                                                                                                                                                */
-
 
2458
/*                                                                                                                                                                                                                                                                                      */
-
 
2459
/*      Description:    Diese Funktion demonstriert die Möglichkeiten der Funktionen findfirst_() findnext_() und changedir_()                                  */
-
 
2460
/*                                                                                                                                                                                                                                                              */
-
 
2461
/*                                                                                                                                                                                                                                                                                      */
-
 
2462
/*      Returnvalue:                                                                                                                                                                                                                                                    */
-
 
2463
/********************************************************************************************************************************************/
-
 
2464
 
-
 
2465
void Test(void)
-
 
2466
{
-
 
2467
        File_t *fp = NULL;
-
 
2468
        Find_t fe;
-
 
2469
        u32 cwd = 0;
-
 
2470
 
-
 
2471
 
-
 
2472
        cwd = Partition.CurrentWorkingDirectory;
-
 
2473
sprintf(text,"\r\n Path: %s\r\n",Partition.PathToCwd); UART1_PutString(text);
-
 
2474
        /* Als Erstes suchen wir uns das erste Unterverzeichnis (ATTR_SUBDIRECTORY) auf der Speicherkarte */
-
 
2475
        if(findfirst_("*.*", ATTR_SUBDIRECTORY, &fe))
-
 
2476
        {
-
 
2477
                /* Danach wechseln wir in in dieses Unterverzeichnis auf der speicherkarte */
-
 
2478
                if(chdir_(fe.name))
-
 
2479
                {
-
 
2480
sprintf(text,"\r\n Path: %s\r\n",Partition.PathToCwd); UART1_PutString(text);
-
 
2481
                        /* Dann finden wir die erste Datei (ATTR_ARCIVE) in diesem Unterverzeichnis */
-
 
2482
                        if(findfirst_("*.*", ATTR_ARCHIVE, &fe))
-
 
2483
                        {
-
 
2484
                                /* Der Name der gefundenen Datei wird ausgegeben */
-
 
2485
                                UART1_PutString("\r\n");
-
 
2486
                                UART1_PutString(fe.name);              
-
 
2487
                                /* nun wir die erste gefundene Datei im Unterverzeichnis lesend geöffnet */
-
 
2488
                                fp = fopen_(fe.name, 'r');
-
 
2489
                                if(fp != NULL){
-
 
2490
                                        /* und die erste Zeile aus dem Inhalt ausgegeben */
-
 
2491
                                        fgets_(text,60,fp);
-
 
2492
                                        UART1_PutString("\r\n");
-
 
2493
                                        UART1_PutString(text);
-
 
2494
                                        fclose_(fp);
-
 
2495
                                }
-
 
2496
                                else {
-
 
2497
                                        UART1_PutString("\r\nfile not found");
-
 
2498
                                }
-
 
2499
 
-
 
2500
                                /* anschließend suchen wir alle weiteren Dateien im aktuellen Unterverzeichnis */              
-
 
2501
                                while(findnext_(&fe))
-
 
2502
                                {
-
 
2503
                                        /* und geben ebenfalls deren Namen */
-
 
2504
                                        UART1_PutString("\r\n");
-
 
2505
                                        UART1_PutString(fe.name);              
-
 
2506
                                        /* sowie nach dem Öffnen ihren Inhalt aus */
-
 
2507
                                        fp = fopen_(fe.name, 'r');
-
 
2508
                                        if(fp != NULL)
-
 
2509
                                        {
-
 
2510
                                                fgets_(text,60,fp);
-
 
2511
                                                UART1_PutString("\r\n");
-
 
2512
                                                UART1_PutString(text);
-
 
2513
                                                fclose_(fp);
-
 
2514
                                        }
-
 
2515
                                }
-
 
2516
                        }
-
 
2517
                }
-
 
2518
        }
-
 
2519
        Partition.CurrentWorkingDirectory = cwd;
-
 
2520
sprintf(text,"\r\n Path: %s\r\n",Partition.PathToCwd); UART1_PutString(text);
-
 
2521
        if(chdir_("/ordner1/ordner12/ordner13"))
-
 
2522
        {
-
 
2523
sprintf(text,"\r\n Path: %s\r\n",Partition.PathToCwd); UART1_PutString(text);
-
 
2524
                fp = fopen_("Datei13.txt", 'r');
-
 
2525
                if(fp != NULL){
-
 
2526
                        /* und die erste Zeile aus dem Inhalt ausgegeben */
-
 
2527
                        fgets_(text,60,fp);
-
 
2528
                        UART1_PutString("\r\n");
-
 
2529
                        UART1_PutString(text);
-
 
2530
                        fclose_(fp);
-
 
2531
                }
-
 
2532
                else {
-
 
2533
                        UART1_PutString("\r\nfile not found");
-
 
2534
                }                              
-
 
2535
        }
-
 
2536
        else
-
 
2537
                UART1_PutString("\r\ndirectory not found");
-
 
2538
        /* jetzt sind wir wieder im Rootverzeichnis */
-
 
2539
        Partition.CurrentWorkingDirectory = cwd;
-
 
2540
sprintf(text,"\r\n Path: %s\r\n",Partition.PathToCwd); UART1_PutString(text);
-
 
2541
}