/*------------------------------------------------------------------------------ -- This file is a part of the libuc, microcontroler library -- Copyright (C) 2012, Alexis Jeandet -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- -- Author : Alexis Jeandet -- Mail : alexis.jeandet@gmail.com -------------------------------------------------------------------------------*/ #ifndef FAT32_H #define FAT32_H #include #include #include #include #include /*BPB (Boot Sector) Offsets */ #define BS_jmpBootoff 0 #define BS_OEMNameoff 3 #define BPB_BytsPerSecoff 11 #define BPB_SecPerClusoff 13 #define BPB_RsvdSecCntoff 14 #define BPB_NumFATsoff 16 #define BPB_RootEntCntoff 17 #define BPB_TotSec16off 19 #define BPB_Mediaoff 21 #define BPB_FATSz16off 22 #define BPB_SecPerTrkoff 24 #define BPB_NumHeadsoff 26 #define BPB_HiddSecoff 28 #define BPB_TotSec32off 32 /*FAT16*/ #define BS_DrvNumFAT16off 36 #define BS_Reserved1FAT16off 37 #define BS_BootSigFAT16off 38 #define BS_VolIDFAT16off 39 #define BS_VolLabFAT16off 43 #define BS_FilSysTypeFAT16off 54 /*FAT32*/ #define BPB_FATSz32off 36 #define BPB_ExtFlagsoff 40 #define BPB_FSVeroff 42 #define BPB_RootClusoff 44 #define BPB_FSInfooff 48 #define BPB_BkBootSecoff 50 #define BPB_Reservedoff 52 #define BS_DrvNumFAT32off 64 #define BS_Reserved1FAT32off 65 #define BS_BootSigFAT32off 66 #define BS_VolIDFAT32off 67 #define BS_VolLabFAT32off 71 #define BS_FilSysTypeFAT32off 82 #define DIR_Nameoff 0 #define DIR_Attroff 0xb #define DIR_FstClusHIoff 0x14 #define DIR_FstClusLOoff 0x1A #define DIR_FileSizeoff 0x1c #define DIR_CrtTimeTenthoff 13 #define DIR_CrtTimeoff 14 #define DIR_CrtDateoff 16 #define DIR_LstAccDateoff 18 #define DIR_WrtTimeoff 22 #define DIR_WrtDateoff 24 #define FATBadpart 1 #define FATBabArg 2 #define FATReadErr 3 #define FATnoErr 0 typedef struct FAT32fs { uint16_t BPB_BytsPerSec; uint16_t BPB_RsvdSecCnt; uint32_t BPB_FATSz32; uint32_t BPB_RootClus; uint32_t fat_begin_lba; uint32_t cluster_begin_lba; uint8_t BPB_SecPerClus; uint8_t BPB_NumFATs; dikpartition* part; }FAT32fs; #define castUI64(val) ((uint64_t)(val)) #define castUI32(val) ((uint32_t)(val)) #define castUI16(val) ((uint16_t)(val)) #define castUI8(val) ((uint8_t)(val)) #define castI64(val) ((int64_t)(val)) #define castI32(val) ((int32_t)(val)) #define castI16(val) ((int16_t)(val)) #define castI8(val) ((int8_t)(val)) #define fat32Ui8_2_Ui32(table,lsBindex) ((uint32_t)((0xFF&(table[lsBindex]))+(0xFF00&(((uint32_t)table[lsBindex+1])<<8))+(0xFF0000&(((uint32_t)table[lsBindex+2])<<16))+(0xFF000000&(((uint32_t)table[lsBindex+3])<<24)))) #define fat32Ui8_2_Ui16(table,lsBindex) ((uint16_t)((0xFF&(table[lsBindex]))+(0xFF00&(((uint16_t)table[lsBindex+1])<<8)))) /* Get the first sector lba of given cluster number*/ #define clusterlba(fs,cluster_number) ((uint32_t)fs->cluster_begin_lba + (((uint32_t)cluster_number) - (2)) * (uint32_t)fs->BPB_SecPerClus) //#define fat32clusterinfatsect(fs,cluster_number) ((((uint32_t)(cluster_number))>>6) + fs->fat_begin_lba) #define fat32clusterinfatsect(fs,cluster_number) ((((uint32_t)(cluster_number))>>7) + fs->fat_begin_lba) #define fat32clusterinfatoff(cluster_number) (((cluster_number)&0x3F)*4) /*Get cluster index in FAT Table from sector address*/ #define fat32masksectorlba(sectorlba,fs) (sectorlba & (castUI32(-1)^castUI32(fs->BPB_SecPerClus-1))) #define fat32sectorlbatoclusternum(fs,sectorlba) (((fat32masksectorlba(castUI32(sectorlba),fs) -(castUI32(fs->cluster_begin_lba)))/castUI32(fs->BPB_SecPerClus))+castUI32(2)) #define fat32extract16b(table, LSBOffset) (uint16_t)(( (uint16_t) ((uint8_t)table[(LSBOffset)]) ) + (uint16_t)( ((uint8_t)table[(LSBOffset)+1]) << 8 )) #define fat32extract32b(table, LSBOffset) (uint32_t)(( (uint32_t) ((uint8_t)table[(LSBOffset)]) ) + (uint32_t)( ((uint8_t)table[(LSBOffset)+1]) << 8 )+ (uint32_t)( ((uint8_t)table[(LSBOffset)+2]) << 16 )+ (uint32_t)( ((uint8_t)table[(LSBOffset)+3]) << 24 )) #ifdef FAT32_PRIVATE #define fat32sectorreadout(fs,fatsec) \ if((lastSecAddrs!=(fatsec)) || (lastFATFS!=(fs))) /*Check if sector already buffered*/ \ {\ if((fs)->part->phy->read((fs)->part->phy,fat32buff,(fatsec),1)!=RES_OK) \ {\ return DIRENT_ReadErr;\ }\ }\ lastSecAddrs=(fatsec);\ lastFATFS=(fs); #endif extern int fat32open(FAT32fs* fs,dikpartition* part); extern int fat32mkdirent(FAT32fs* fs,ucdirent* dirent); extern int fat32getVolName(FAT32fs* fs,char* Name); extern int fat32getrootfirstent(ucdirent* entry); extern int fat32nextdirent(ucdirent* entry); extern int fat32nextsectorlba(FAT32fs* fs,uint32_t lastsector_lba,uint32_t* nextsector_lba); extern int fat32prevsectorlba(FAT32fs* fs,uint32_t lastsector_lba,uint32_t *nextsector_lba); extern uint32_t fat32getdirentlba(ucdirent* entry); extern int fat32getdirentname(ucdirent* entry,char* nameBuffer); #endif