Subversion Repositories NaviCtrl

Rev

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

Rev 171 Rev 210
Line 296... Line 296...
296
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
296
        u16     SectorsPerFat;                  // how many sectors does a fat16 contain?
297
        u32 FirstFatSector;                     // sector of the start of the fat
297
        u32 FirstFatSector;                     // sector of the start of the fat
298
        u32 FirstRootDirSector;         // sector of the rootdirectory
298
        u32 FirstRootDirSector;         // sector of the rootdirectory
299
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
299
        u32 FirstDataSector;            // sector of the first cluster containing data (cluster2).
300
        u32 LastDataSector;                     // the last data sector of the partition
300
        u32 LastDataSector;                     // the last data sector of the partition
-
 
301
        u8 VolumeLabel[12];                     // the volume label
301
} Partition_t;
302
} Partition_t;
Line 302... Line 303...
302
 
303
 
Line 303... Line 304...
303
Partition_t     Partition;                                      // Structure holds partition information
304
Partition_t     Partition;                                      // Structure holds partition information
Line 389... Line 390...
389
/****************************************************************************************************************************************/
390
/****************************************************************************************************************************************/
390
/*      Function:               SeperateDirName(s8*, s8*);                                                                                                                                                                              */
391
/*      Function:               SeperateDirName(s8*, s8*);                                                                                                                                                                              */
391
/*                                                                                                                                                                                                                                                                              */
392
/*                                                                                                                                                                                                                                                                              */
392
/*      Description:    This function seperates the first dirname from filepath and brings them                                                                                         */
393
/*      Description:    This function seperates the first dirname from filepath and brings them                                                                                         */
393
/*                                      into the needed format ('test.txt' -> 'TEST    TXT')                                                                                                                            */
394
/*                                      into the needed format ('test.txt' -> 'TEST    TXT')                                                                                                                            */
394
/*                                      The subpath is the pointer to the remaining substring if the filepath                                                                                           */
395
/*                                      The subpath is the pointer to the remaining substring of the filepath                                                                                           */
395
/*                                                                                                                                                                                                                                                                              */
396
/*                                                                                                                                                                                                                                                                              */
396
/*      Returnvalue:    Return NULL on error or pointer to subpath                                                                                                                                                                                                      */
397
/*      Returnvalue:    Return NULL on error or pointer to subpath                                                                                                                                                                                                      */
397
/****************************************************************************************************************************************/
398
/****************************************************************************************************************************************/
398
s8* SeperateDirName(const s8 *filepath, s8 *dirname)
399
s8* SeperateDirName(const s8 *filepath, s8 *dirname)
399
{
400
{
Line 480... Line 481...
480
        return ((u16)((sector - Partition.FirstDataSector) / Partition.SectorsPerCluster) + 2);
481
        return ((u16)((sector - Partition.FirstDataSector) / Partition.SectorsPerCluster) + 2);
481
}
482
}
Line 482... Line 483...
482
 
483
 
483
 
484
 
484
/****************************************************************************************************************************************/
485
/****************************************************************************************************************************************/
485
/*      Function:       Fat16_IsValid(void);                                                                                                                                                                                                            */
486
/*      Function:       Fat16_IsValid(void);                                                                                                                                                                                                    */
486
/*                                                                                                                                                                                                                                                                              */
487
/*                                                                                                                                                                                                                                                                              */
487
/*      Description:    This function return the Fat 15 filesystem state                                                                                                                                                        */
488
/*      Description:    This function return the Fat 16 filesystem state                                                                                                                                        */
488
/*                                                                                                                                                                                                                                                                              */
489
/*                                                                                                                                                                                                                                                                              */
489
/*      Returnvalue: The function returns "1" on success                                                                                                                                                                        */
490
/*      Returnvalue: The function returns "1" on success                                                                                                                                                                        */
490
/****************************************************************************************************************************************/
491
/****************************************************************************************************************************************/
491
u8 Fat16_IsValid(void)
492
u8 Fat16_IsValid(void)
492
{
493
{
Line 493... Line -...
493
        return(Partition.IsValid);
-
 
494
}
494
        return(Partition.IsValid);
495
 
495
}
496
 
496
 
497
/****************************************************************************************************************************************/
497
/****************************************************************************************************************************************/
498
/*      Function:       Fat16_Deinit(void);                                                                                                                                                                                                             */
498
/*      Function:       Fat16_Deinit(void);                                                                                                                                                                                                             */
Line 516... Line 516...
516
                }
516
                }
Line 517... Line 517...
517
 
517
 
518
        }
518
        }
519
        SDC_Deinit();                   // uninitialize interface to sd-card
519
        SDC_Deinit();                   // uninitialize interface to sd-card
-
 
520
        Partition.IsValid = 0;  // mark data in partition structure as invalid
520
        Partition.IsValid = 0;  // mark data in partition structure as invalid
521
        Partition.VolumeLabel[0]='\0';
521
        UART1_PutString("ok");
522
        UART1_PutString("ok");
522
        return(returnvalue);
523
        return(returnvalue);
Line 523... Line 524...
523
}
524
}
Line 593... Line 594...
593
                goto end;
594
                goto end;
594
        }
595
        }
595
        Partition.SectorsPerCluster             = VBR->SectorsPerCluster;                       // Number of sectors per cluster. Depends on the memorysize of the sd-card.
596
        Partition.SectorsPerCluster             = VBR->SectorsPerCluster;                       // Number of sectors per cluster. Depends on the memorysize of the sd-card.
596
        Partition.FatCopies                     = VBR->NoFATCopies;                                     // Number of fatcopies.
597
        Partition.FatCopies                     = VBR->NoFATCopies;                                     // Number of fatcopies.
597
        Partition.MaxRootEntries                = VBR->MaxRootEntries;                          // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
598
        Partition.MaxRootEntries                = VBR->MaxRootEntries;                          // How many Entries are possible in the rootdirectory (FAT16 allows max. 512 entries).
598
        Partition.SectorsPerFat                 = VBR->SectorsPerFAT;                           // The number of sectors per FAT.
599
        Partition.SectorsPerFat                 = VBR->SectorsPerFAT;                           // The number of sectors per FAT                                // copy volume label
-
 
600
        Partition.VolumeLabel[0] = '\0';                                                                        // set string terminator
Line 599... Line 601...
599
 
601
 
600
        /* Calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster. */
602
        /* Calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster. */
601
        // Calculate the position of the FileAllocationTable:
603
        // Calculate the position of the FileAllocationTable:
602
        // Start + # of Reserved Sectors
604
        // Start + # of Reserved Sectors
Line 844... Line 846...
844
        u8 buffer[BYTES_PER_SECTOR];
846
        u8 buffer[BYTES_PER_SECTOR];
845
        u32 sector_in_buffer = 0;
847
        u32 sector_in_buffer = 0;
846
        u8 repeat = 0;
848
        u8 repeat = 0;
Line 847... Line 849...
847
 
849
 
848
        if(!Partition.IsValid) return 0;
-
 
849
 
850
        if(!Partition.IsValid) return 0;
-
 
851
        cluster = StartCluster; // init chain trace
-
 
852
        // if start cluster is equal to the last cluster we are done
-
 
853
        if(FAT16_CLUSTER_LAST_MIN <= cluster) return 1;
850
        cluster = StartCluster; // init chain trace
854
 
851
        // calculate byte offset in the fat for corresponding entry
855
        // calculate byte offset in the fat for corresponding entry
852
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
856
        fat_byte_offset = ((u32)cluster)<<1; // two FAT bytes (16 bits) for every cluster
853
        // calculate the sector that contains the current cluster within the fat
857
        // calculate the sector that contains the current cluster within the fat
854
        sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
858
        sector = Partition.FirstFatSector + ( fat_byte_offset / BYTES_PER_SECTOR);
Line 876... Line 880...
876
                // calculate byte offset of the current cluster within that fat sector
880
                // calculate byte offset of the current cluster within that fat sector
877
                byte = fat_byte_offset % BYTES_PER_SECTOR;
881
                byte = fat_byte_offset % BYTES_PER_SECTOR;
878
                // if new sector is not the sector in buffer or the last cluster in the chain was traced
882
                // if new sector is not the sector in buffer or the last cluster in the chain was traced
879
                if((sector != sector_in_buffer) || !repeat)
883
                if((sector != sector_in_buffer) || !repeat)
880
                {       // write sector in buffer
884
                {       // write sector in buffer
881
                        if(SD_SUCCESS != SDC_PutSector(sector_in_buffer,buffer))
885
                        if(SD_SUCCESS != SDC_PutSector(sector_in_buffer,buffer))
882
                        {
886
                        {
883
                                Fat16_Deinit();
887
                                Fat16_Deinit();
884
                                return 0;
888
                                return 0;
885
                        }
889
                        }
886
                }
890
                }
Line 1414... Line 1418...
1414
                                }
1418
                                }
1415
                                else
1419
                                else
1416
                                {       // file is not marked as read only --> goto start of file
1420
                                {       // file is not marked as read only --> goto start of file
1417
                                        // free all clusters of that file
1421
                                        // free all clusters of that file
1418
                                        DeleteClusterChain(SectorToFat16Cluster(file->FirstSectorOfFirstCluster));
1422
                                        DeleteClusterChain(SectorToFat16Cluster(file->FirstSectorOfFirstCluster));
1419
                                        // mar an empy cluster as the last one and store the corresponding sector
1423
                                        // mark an empy cluster as the last one and store the corresponding sector
1420
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(FindNextFreeCluster(file));
1424
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(FindNextFreeCluster(file));
1421
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
1425
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
1422
                                        file->SectorOfCurrCluster = 0;
1426
                                        file->SectorOfCurrCluster = 0;
1423
                                        file->ByteOfCurrSector = 0;
1427
                                        file->ByteOfCurrSector = 0;
1424
                                        file->Size = 0;
1428
                                        file->Size = 0;
Line 1834... Line 1838...
1834
        {
1838
        {
1835
                return(1);
1839
                return(1);
1836
        }
1840
        }
1837
}
1841
}
Line -... Line 1842...
-
 
1842
 
-
 
1843
/****************************************************************************************************************************************************/
-
 
1844
/* Function:    s8* FAT16_GetVolumeLabel(void)                                                                                                                                                                                                                  */
-
 
1845
/*                                                                                                                                                                                                                                                                                                      */
-
 
1846
/* Description: This function returns the volume label                                                                                                                                                                                          */
-
 
1847
/*                                                                                                                                                                                                                                                                                                      */
-
 
1848
/* Returnvalue: This function returns the pointer to the volume label or NULL if not found.                                                                                                                     */
-
 
1849
/****************************************************************************************************************************************************/
-
 
1850
s8* FAT16_GetVolumeLabel(void)
-
 
1851
{
-
 
1852
        s8              *pVolumeLabel = NULL;
-
 
1853
        u32             dir_sector, max_dir_sector, curr_sector;
-
 
1854
        u16     dir_entry = 0;
Line -... Line 1855...
-
 
1855
        u8              i = 0;
-
 
1856
 
-
 
1857
        DirEntry_t * dir;
-
 
1858
        File_t *file = NULL;
-
 
1859
       
-
 
1860
        // if Partition is not valud return NULL
-
 
1861
        if(!Partition.IsValid) return(pVolumeLabel);
-
 
1862
        // if Volume label was read before return it
-
 
1863
        if(Partition.VolumeLabel[0]!= '\0') return (Partition.VolumeLabel);
-
 
1864
        // try to catch a file pointer
-
 
1865
        file = LockFilePointer();
-
 
1866
        if(file == NULL) return(pVolumeLabel);
-
 
1867
        // search dir entries direct within the root directory area
-
 
1868
        file->DirectorySector = 0;
-
 
1869
        max_dir_sector = (Partition.MaxRootEntries * DIRENTRY_SIZE)/BYTES_PER_SECTOR;
-
 
1870
        file->FirstSectorOfFirstCluster = Partition.FirstRootDirSector;
-
 
1871
       
-
 
1872
        // update current file data area position to start of first cluster
-
 
1873
        file->FirstSectorOfCurrCluster  = file->FirstSectorOfFirstCluster;
-
 
1874
        file->SectorOfCurrCluster               = 0;
-
 
1875
        file->ByteOfCurrSector                  = 0;
-
 
1876
 
-
 
1877
        dir_sector = 0; // reset sector counter within a new cluster
-
 
1878
        do // loop over all sectors of the root directory
-
 
1879
        {
-
 
1880
                curr_sector = file->FirstSectorOfCurrCluster + dir_sector;      // calculate sector number
-
 
1881
                file->SectorInCache = curr_sector;                                                      // upate the sector number of file cache.
-
 
1882
                if(SD_SUCCESS != SDC_GetSector(file->SectorInCache, file->Cache))// read the sector
-
 
1883
                {
-
 
1884
                        Fat16_Deinit();
-
 
1885
                        return(pVolumeLabel);
-
 
1886
                }
-
 
1887
                dir = (DirEntry_t *)file->Cache;                                                        // set pointer to directory
-
 
1888
                // search all directory entries within that sector
-
 
1889
                for(dir_entry = 0; dir_entry < DIRENTRIES_PER_SECTOR; dir_entry++)
-
 
1890
                {   // check for existing dir entry
-
 
1891
                        switch((u8)dir[dir_entry].Name[0])
-
 
1892
                        {
-
 
1893
                                case SLOT_EMPTY:
-
 
1894
                                case SLOT_DELETED:
-
 
1895
                                        // ignore empty or deleted dir entries
-
 
1896
                                        break;
-
 
1897
                                default:
-
 
1898
                                        // check attributes for volume label
-
 
1899
                                        if ((dir[dir_entry].Attribute & ATTR_VOLUMELABEL) != ATTR_VOLUMELABEL) break; // attribute must match
-
 
1900
                                        // (first 11 characters include 8 chars of basename and 3 chars extension.)
-
 
1901
                                        for(i = 0; i<11;i++) Partition.VolumeLabel[i] = dir[dir_entry].Name[i];
-
 
1902
                                        Partition.VolumeLabel[11] = '\0'; // terminate string
-
 
1903
                                        file->Attribute = dir[dir_entry].Attribute; // store attribute of found dir entry
-
 
1904
                                        file->FirstSectorOfFirstCluster = Fat16ClusterToSector(dir[dir_entry].StartCluster); // set sector of first data cluster
-
 
1905
                                        file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster;
-
 
1906
                                        file->SectorOfCurrCluster = 0;
-
 
1907
                                        file->ByteOfCurrSector = 0;
-
 
1908
                                        file->DirectorySector = curr_sector; // current sector
-
 
1909
                                        file->DirectoryIndex  = dir_entry; // current direntry in current sector
-
 
1910
                                        file->Size = dir[dir_entry].Size;
-
 
1911
                                        dir_entry = DIRENTRIES_PER_SECTOR;      // stop for-loop
-
 
1912
                                        pVolumeLabel =  Partition.VolumeLabel;
-
 
1913
                        } // end of first byte of name check
-
 
1914
                }
-
 
1915
                dir_sector++; // search next sector
-
 
1916
        // stop if we reached the end of the cluster or the end of the root dir
-
 
1917
        }while((dir_sector < max_dir_sector) && (!pVolumeLabel));
-
 
1918
 
-
 
1919
        UnlockFilePointer(file);