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); |