int fatfs_fat_set_cluster(struct fatfs *fs, UINT32 cluster, UINT32 next_cluster) { struct sector_buffer *pbuf; UINT32 fat_sector_offset, position; // Find which sector of FAT table to read if (fs->fat_type == FAT_TYPE_16) fat_sector_offset = cluster / 256; else fat_sector_offset = cluster / 128; // Read FAT sector into buffer pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); if (!pbuf) return 0; if (fs->fat_type == FAT_TYPE_16) { // Find 16 bit entry of current sector relating to cluster number position = (cluster - (fat_sector_offset * 256)) * 2; // Write Next Clusters value to Sector Buffer FAT16_SET_16BIT_WORD(pbuf, (UINT16)position, ((UINT16)next_cluster)); } else { // Find 32 bit entry of current sector relating to cluster number position = (cluster - (fat_sector_offset * 128)) * 4; // Write Next Clusters value to Sector Buffer FAT32_SET_32BIT_WORD(pbuf, (UINT16)position, next_cluster); } return 1; }
//----------------------------------------------------------------------------- // fatfs_count_free_clusters: //----------------------------------------------------------------------------- UINT32 fatfs_count_free_clusters(struct fatfs *fs) { UINT32 i,j; UINT32 count = 0; struct sector_buffer *pbuf; for (i = 0; i < fs->fat_sectors; i++) { // Read FAT sector into buffer pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba + i); if (!pbuf) break; for (j = 0; j < FAT_SECTOR_SIZE; ) { if (fs->fat_type == FAT_TYPE_16) { if (FAT16_GET_16BIT_WORD(pbuf, (UINT16)j) == 0) count++; j += 2; } else { if (FAT32_GET_32BIT_WORD(pbuf, (UINT16)j) == 0) count++; j += 4; } } } return count; }
int fatfs_find_blank_cluster(struct fatfs *fs, UINT32 start_cluster, UINT32 *free_cluster) { UINT32 fat_sector_offset, position; UINT32 nextcluster; UINT32 current_cluster = start_cluster; struct sector_buffer *pbuf; do { // Find which sector of FAT table to read if (fs->fat_type == FAT_TYPE_16) fat_sector_offset = current_cluster / 256; else fat_sector_offset = current_cluster / 128; if ( fat_sector_offset < fs->fat_sectors) { // Read FAT sector into buffer pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); if (!pbuf) return 0; if (fs->fat_type == FAT_TYPE_16) { // Find 32 bit entry of current sector relating to cluster number position = (current_cluster - (fat_sector_offset * 256)) * 2; // Read Next Clusters value from Sector Buffer nextcluster = FAT16_GET_16BIT_WORD(pbuf, (UINT16)position); } else { // Find 32 bit entry of current sector relating to cluster number position = (current_cluster - (fat_sector_offset * 128)) * 4; // Read Next Clusters value from Sector Buffer nextcluster = FAT32_GET_32BIT_WORD(pbuf, (UINT16)position); // Mask out MS 4 bits (its 28bit addressing) nextcluster = nextcluster & 0x0FFFFFFF; } if (nextcluster !=0 ) current_cluster++; } else // Otherwise, run out of FAT sectors to check... return 0; } while (nextcluster != 0x0); // Found blank entry *free_cluster = current_cluster; return 1; }
//----------------------------------------------------------------------------- // fatfs_find_next_cluster: Return cluster number of next cluster in chain by // reading FAT table and traversing it. Return 0xffffffff for end of chain. //----------------------------------------------------------------------------- UINT32 fatfs_find_next_cluster(struct fatfs *fs, UINT32 current_cluster) { UINT32 fat_sector_offset, position; UINT32 nextcluster; struct sector_buffer *pbuf; // Why is '..' labelled with cluster 0 when it should be 2 ?? if (current_cluster == 0) current_cluster = 2; // Find which sector of FAT table to read if (fs->fat_type == FAT_TYPE_16) fat_sector_offset = current_cluster / 256; else fat_sector_offset = current_cluster / 128; // Read FAT sector into buffer pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); if (!pbuf) return (FAT32_LAST_CLUSTER); if (fs->fat_type == FAT_TYPE_16) { // Find 32 bit entry of current sector relating to cluster number position = (current_cluster - (fat_sector_offset * 256)) * 2; // Read Next Clusters value from Sector Buffer nextcluster = FAT16_GET_16BIT_WORD(pbuf, (UINT16)position); // If end of chain found if (nextcluster >= 0xFFF8 && nextcluster <= 0xFFFF) return (FAT32_LAST_CLUSTER); } else { // Find 32 bit entry of current sector relating to cluster number position = (current_cluster - (fat_sector_offset * 128)) * 4; // Read Next Clusters value from Sector Buffer nextcluster = FAT32_GET_32BIT_WORD(pbuf, (UINT16)position); // Mask out MS 4 bits (its 28bit addressing) nextcluster = nextcluster & 0x0FFFFFFF; // If end of chain found if (nextcluster >= 0x0FFFFFF8 && nextcluster <= 0x0FFFFFFF) return (FAT32_LAST_CLUSTER); } // Else return next cluster return (nextcluster); }
//----------------------------------------------------------------------------- // fatfs_set_fs_info_next_free_cluster: Write the next free cluster to the FSINFO table //----------------------------------------------------------------------------- void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, UINT32 newValue) { if (fs->fat_type == FAT_TYPE_16) ; else { // Load sector to change it struct sector_buffer *pbuf = fatfs_fat_read_sector(fs, fs->lba_begin+fs->fs_info_sector); if (!pbuf) return ; // Change FAT32_SET_32BIT_WORD(pbuf, 492, newValue); fs->next_free_cluster = newValue; } }
//----------------------------------------------------------------------------- // fatfs_set_fs_info_next_free_cluster: Write the next free cluster to the FSINFO table //----------------------------------------------------------------------------- void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, uint32 newValue) { if (fs->fat_type == FAT_TYPE_16) ; else { // Load sector to change it struct fat_buffer *pbuf = fatfs_fat_read_sector(fs, fs->lba_begin+fs->fs_info_sector); if (!pbuf) return ; // Change FAT32_SET_32BIT_WORD(pbuf, 492, newValue); fs->next_free_cluster = newValue; // Write back FSINFO sector to disk if (fs->disk_io.write_media) fs->disk_io.write_media(pbuf->address, pbuf->sector, 1); // Invalidate cache entry pbuf->address = FAT32_INVALID_CLUSTER; pbuf->dirty = 0; } }