Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SdFat.h
00001 /* Arduino SdFat Library 00002 * Copyright (C) 2009 by William Greiman 00003 * 00004 * This file is part of the Arduino SdFat Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino SdFat Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00020 #ifndef SdFat_h 00021 #define SdFat_h 00022 /** 00023 * \file 00024 * SdFile and SdVolume classes 00025 */ 00026 #include "mbed.h" 00027 #include "Sd2Card.h" 00028 #include "FatStructs.h" 00029 #include "Serial.h" 00030 //------------------------------------------------------------------------------ 00031 /** 00032 * Allow use of deprecated functions if non-zero 00033 */ 00034 #define ALLOW_DEPRECATED_FUNCTIONS 1 00035 //------------------------------------------------------------------------------ 00036 // forward declaration since SdVolume is used in SdFile 00037 class SdVolume; 00038 //============================================================================== 00039 // SdFile class 00040 00041 // flags for ls() 00042 /** ls() flag to print modify date */ 00043 uint8_t const LS_DATE = 1; 00044 /** ls() flag to print file size */ 00045 uint8_t const LS_SIZE = 2; 00046 /** ls() flag for recursive list of subdirectories */ 00047 uint8_t const LS_R = 4; 00048 00049 // use the gnu style oflag in open() 00050 /** open() oflag for reading */ 00051 uint8_t const O_READ = 0X01; 00052 /** open() oflag - same as O_READ */ 00053 uint8_t const O_RDONLY = O_READ; 00054 /** open() oflag for write */ 00055 uint8_t const O_WRITE = 0X02; 00056 /** open() oflag - same as O_WRITE */ 00057 uint8_t const O_WRONLY = O_WRITE; 00058 /** open() oflag for reading and writing */ 00059 uint8_t const O_RDWR = (O_READ | O_WRITE); 00060 /** open() oflag mask for access modes */ 00061 uint8_t const O_ACCMODE = (O_READ | O_WRITE); 00062 /** The file offset shall be set to the end of the file prior to each write. */ 00063 uint8_t const O_APPEND = 0X04; 00064 /** synchronous writes - call sync() after each write */ 00065 uint8_t const O_SYNC = 0X08; 00066 /** create the file if nonexistent */ 00067 uint8_t const O_CREAT = 0X10; 00068 /** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ 00069 uint8_t const O_EXCL = 0X20; 00070 /** truncate the file to zero length */ 00071 uint8_t const O_TRUNC = 0X40; 00072 00073 // flags for timestamp 00074 /** set the file's last access date */ 00075 uint8_t const T_ACCESS = 1; 00076 /** set the file's creation date and time */ 00077 uint8_t const T_CREATE = 2; 00078 /** Set the file's write date and time */ 00079 uint8_t const T_WRITE = 4; 00080 // values for type_ 00081 /** This SdFile has not been opened. */ 00082 uint8_t const FAT_FILE_TYPE_CLOSED = 0; 00083 /** SdFile for a file */ 00084 uint8_t const FAT_FILE_TYPE_NORMAL = 1; 00085 /** SdFile for a FAT16 root directory */ 00086 uint8_t const FAT_FILE_TYPE_ROOT16 = 2; 00087 /** SdFile for a FAT32 root directory */ 00088 uint8_t const FAT_FILE_TYPE_ROOT32 = 3; 00089 /** SdFile for a subdirectory */ 00090 uint8_t const FAT_FILE_TYPE_SUBDIR = 4; 00091 /** Test value for directory type */ 00092 uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; 00093 00094 /** date field for FAT directory entry */ 00095 static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { 00096 return (year - 1980) << 9 | month << 5 | day; 00097 } 00098 /** year part of FAT directory date field */ 00099 static inline uint16_t FAT_YEAR(uint16_t fatDate) { 00100 return 1980 + (fatDate >> 9); 00101 } 00102 /** month part of FAT directory date field */ 00103 static inline uint8_t FAT_MONTH(uint16_t fatDate) { 00104 return (fatDate >> 5) & 0XF; 00105 } 00106 /** day part of FAT directory date field */ 00107 static inline uint8_t FAT_DAY(uint16_t fatDate) { 00108 return fatDate & 0X1F; 00109 } 00110 /** time field for FAT directory entry */ 00111 static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { 00112 return hour << 11 | minute << 5 | second >> 1; 00113 } 00114 /** hour part of FAT directory time field */ 00115 static inline uint8_t FAT_HOUR(uint16_t fatTime) { 00116 return fatTime >> 11; 00117 } 00118 /** minute part of FAT directory time field */ 00119 static inline uint8_t FAT_MINUTE(uint16_t fatTime) { 00120 return(fatTime >> 5) & 0X3F; 00121 } 00122 /** second part of FAT directory time field */ 00123 static inline uint8_t FAT_SECOND(uint16_t fatTime) { 00124 return 2*(fatTime & 0X1F); 00125 } 00126 /** Default date for file timestamps is 1 Jan 2000 */ 00127 uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; 00128 /** Default time for file timestamp is 1 am */ 00129 uint16_t const FAT_DEFAULT_TIME = (1 << 11); 00130 //------------------------------------------------------------------------------ 00131 /** 00132 * \class SdFile 00133 * \brief Access FAT16 and FAT32 files on SD and SDHC cards. 00134 */ 00135 class SdFile : public Print { 00136 public: 00137 /** Create an instance of SdFile. */ 00138 SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} 00139 /** 00140 * writeError is set to true if an error occurs during a write(). 00141 * Set writeError to false before calling print() and/or write() and check 00142 * for true after calls to print() and/or write(). 00143 */ 00144 //bool writeError; 00145 /** 00146 * Cancel unbuffered reads for this file. 00147 * See setUnbufferedRead() 00148 */ 00149 void clearUnbufferedRead(void) { 00150 flags_ &= ~F_FILE_UNBUFFERED_READ; 00151 } 00152 uint8_t close(void); 00153 uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); 00154 uint8_t createContiguous(SdFile* dirFile, 00155 const char* fileName, uint32_t size); 00156 /** \return The current cluster number for a file or directory. */ 00157 uint32_t curCluster (void) const {return curCluster_;} 00158 /** \return The current position for a file or directory. */ 00159 uint32_t curPosition (void) const {return curPosition_;} 00160 /** 00161 * Set the date/time callback function 00162 * 00163 * \param[in] dateTime The user's call back function. The callback 00164 * function is of the form: 00165 * 00166 * \code 00167 * void dateTime(uint16_t* date, uint16_t* time) { 00168 * uint16_t year; 00169 * uint8_t month, day, hour, minute, second; 00170 * 00171 * // User gets date and time from GPS or real-time clock here 00172 * 00173 * // return date using FAT_DATE macro to format fields 00174 * *date = FAT_DATE(year, month, day); 00175 * 00176 * // return time using FAT_TIME macro to format fields 00177 * *time = FAT_TIME(hour, minute, second); 00178 * } 00179 * \endcode 00180 * 00181 * Sets the function that is called when a file is created or when 00182 * a file's directory entry is modified by sync(). All timestamps, 00183 * access, creation, and modify, are set when a file is created. 00184 * sync() maintains the last access date and last modify date/time. 00185 * 00186 * See the timestamp() function. 00187 */ 00188 static void dateTimeCallback( 00189 void (*dateTime)(uint16_t* date, uint16_t* time)) { 00190 dateTime_ = dateTime; 00191 } 00192 /** 00193 * Cancel the date/time callback function. 00194 */ 00195 static void dateTimeCallbackCancel(void) { 00196 // use explicit zero since NULL is not defined for Sanguino 00197 dateTime_ = 0; 00198 } 00199 /** \return Address of the block that contains this file's directory. */ 00200 uint32_t dirBlock (void) const {return dirBlock_;} 00201 uint8_t dirEntry(dir_t* dir); 00202 /** \return Index of this file's directory in the block dirBlock. */ 00203 uint8_t dirIndex (void) const {return dirIndex_;} 00204 static void dirName(const dir_t& dir, char* name); 00205 /** \return The total number of bytes in a file or directory. */ 00206 uint32_t fileSize (void) const {return fileSize_;} 00207 /** \return The first cluster number for a file or directory. */ 00208 uint32_t firstCluster (void) const {return firstCluster_;} 00209 /** \return True if this is a SdFile for a directory else false. */ 00210 uint8_t isDir (void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} 00211 /** \return True if this is a SdFile for a file else false. */ 00212 uint8_t isFile (void) const {return type_ == FAT_FILE_TYPE_NORMAL;} 00213 /** \return True if this is a SdFile for an open file/directory else false. */ 00214 uint8_t isOpen (void) const {return type_ != FAT_FILE_TYPE_CLOSED;} 00215 /** \return True if this is a SdFile for a subdirectory else false. */ 00216 uint8_t isSubDir (void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} 00217 /** \return True if this is a SdFile for the root directory. */ 00218 uint8_t isRoot (void) const { 00219 return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; 00220 } 00221 void ls(uint8_t flags = 0, uint8_t indent = 0); 00222 uint8_t makeDir(SdFile* dir, const char* dirName); 00223 uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); 00224 uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); 00225 00226 uint8_t openRoot(SdVolume* vol); 00227 static void printDirName(const dir_t& dir, uint8_t width); 00228 static void printFatDate(uint16_t fatDate); 00229 static void printFatTime(uint16_t fatTime); 00230 static void printTwoDigits(uint8_t v); 00231 /** 00232 * Read the next byte from a file. 00233 * 00234 * \return For success read returns the next byte in the file as an int. 00235 * If an error occurs or end of file is reached -1 is returned. 00236 */ 00237 int16_t read(void) { 00238 uint8_t b; 00239 return read(&b, 1) == 1 ? b : -1; 00240 } 00241 int16_t read(void* buf, uint16_t nbyte); 00242 int8_t readDir(dir_t* dir); 00243 static uint8_t remove(SdFile* dirFile, const char* fileName); 00244 uint8_t remove(void); 00245 /** Set the file's current position to zero. */ 00246 void rewind(void) { 00247 curPosition_ = curCluster_ = 0; 00248 } 00249 uint8_t rmDir(void); 00250 uint8_t rmRfStar(void); 00251 /** Set the files position to current position + \a pos. See seekSet(). */ 00252 uint8_t seekCur(uint32_t pos) { 00253 return seekSet(curPosition_ + pos); 00254 } 00255 /** 00256 * Set the files current position to end of file. Useful to position 00257 * a file for append. See seekSet(). 00258 */ 00259 uint8_t seekEnd(void) {return seekSet(fileSize_);} 00260 uint8_t seekSet(uint32_t pos); 00261 /** 00262 * Use unbuffered reads to access this file. Used with Wave 00263 * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. 00264 * 00265 * Not recommended for normal applications. 00266 */ 00267 void setUnbufferedRead(void) { 00268 if (isFile ()) flags_ |= F_FILE_UNBUFFERED_READ; 00269 } 00270 uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, 00271 uint8_t hour, uint8_t minute, uint8_t second); 00272 uint8_t sync(void); 00273 /** Type of this SdFile. You should use isFile() or isDir() instead of type() 00274 * if possible. 00275 * 00276 * \return The file or directory type. 00277 */ 00278 uint8_t type(void) const {return type_;} 00279 uint8_t truncate(uint32_t size); 00280 /** \return Unbuffered read flag. */ 00281 uint8_t unbufferedRead (void) const { 00282 return flags_ & F_FILE_UNBUFFERED_READ; 00283 } 00284 /** \return SdVolume that contains this file. */ 00285 SdVolume* volume (void) const {return vol_;} 00286 size_t write(uint8_t b); 00287 size_t write(const void* buf, uint16_t nbyte); 00288 size_t write(const char* str); 00289 void write_P(PGM_P str); 00290 void writeln_P(PGM_P str); 00291 //------------------------------------------------------------------------------ 00292 #if ALLOW_DEPRECATED_FUNCTIONS 00293 // Deprecated functions - suppress cpplint warnings with NOLINT comment 00294 /** \deprecated Use: 00295 * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); 00296 */ 00297 uint8_t contiguousRange (uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT 00298 return contiguousRange(&bgnBlock, &endBlock); 00299 } 00300 /** \deprecated Use: 00301 * uint8_t SdFile::createContiguous(SdFile* dirFile, 00302 * const char* fileName, uint32_t size) 00303 */ 00304 uint8_t createContiguous(SdFile& dirFile, // NOLINT 00305 const char* fileName, uint32_t size) { 00306 return createContiguous(&dirFile, fileName, size); 00307 } 00308 00309 /** 00310 * \deprecated Use: 00311 * static void SdFile::dateTimeCallback( 00312 * void (*dateTime)(uint16_t* date, uint16_t* time)); 00313 */ 00314 static void dateTimeCallback( 00315 void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT 00316 oldDateTime_ = dateTime; 00317 dateTime_ = dateTime ? oldToNew : 0; 00318 } 00319 /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ 00320 uint8_t dirEntry (dir_t& dir) {return dirEntry (&dir);} // NOLINT 00321 /** \deprecated Use: 00322 * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); 00323 */ 00324 uint8_t makeDir (SdFile& dir, const char* dirName) { // NOLINT 00325 return makeDir(&dir, dirName); 00326 } 00327 /** \deprecated Use: 00328 * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); 00329 */ 00330 uint8_t open(SdFile& dirFile, // NOLINT 00331 const char* fileName, uint8_t oflag) { 00332 return open(&dirFile, fileName, oflag); 00333 } 00334 /** \deprecated Do not use in new apps */ 00335 uint8_t open (SdFile& dirFile, const char* fileName) { // NOLINT 00336 return open(dirFile, fileName, O_RDWR); 00337 } 00338 /** \deprecated Use: 00339 * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); 00340 */ 00341 uint8_t open (SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT 00342 return open(&dirFile, index, oflag); 00343 } 00344 /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ 00345 uint8_t openRoot (SdVolume& vol) {return openRoot (&vol);} // NOLINT 00346 00347 /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ 00348 int8_t readDir (dir_t& dir) {return readDir (&dir);} // NOLINT 00349 /** \deprecated Use: 00350 * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); 00351 */ 00352 static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT 00353 return remove(&dirFile, fileName); 00354 } 00355 //------------------------------------------------------------------------------ 00356 // rest are private 00357 private: 00358 static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT 00359 static void oldToNew(uint16_t* date, uint16_t* time) { 00360 uint16_t d; 00361 uint16_t t; 00362 oldDateTime_(d, t); 00363 *date = d; 00364 *time = t; 00365 } 00366 #endif // ALLOW_DEPRECATED_FUNCTIONS 00367 private: 00368 // bits defined in flags_ 00369 // should be 0XF 00370 static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); 00371 // available bits 00372 static uint8_t const F_UNUSED = 0X30; 00373 // use unbuffered SD read 00374 static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; 00375 // sync of directory entry required 00376 static uint8_t const F_FILE_DIR_DIRTY = 0X80; 00377 00378 // make sure F_OFLAG is ok 00379 #if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) 00380 #error flags_ bits conflict 00381 #endif // flags_ bits 00382 00383 // private data 00384 uint8_t flags_; // See above for definition of flags_ bits 00385 uint8_t type_; // type of file see above for values 00386 uint32_t curCluster_; // cluster for current file position 00387 uint32_t curPosition_; // current file position in bytes from beginning 00388 uint32_t dirBlock_; // SD block that contains directory entry for file 00389 uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF 00390 uint32_t fileSize_; // file size in bytes 00391 uint32_t firstCluster_; // first cluster of file 00392 SdVolume* vol_; // volume where file is located 00393 00394 // private functions 00395 uint8_t addCluster(void); 00396 uint8_t addDirCluster(void); 00397 dir_t* cacheDirEntry(uint8_t action); 00398 static void (*dateTime_)(uint16_t* date, uint16_t* time); 00399 static uint8_t make83Name(const char* str, uint8_t* name); 00400 uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); 00401 dir_t* readDirCache(void); 00402 }; 00403 //============================================================================== 00404 // SdVolume class 00405 /** 00406 * \brief Cache for an SD data block 00407 */ 00408 union cache_t { 00409 /** Used to access cached file data blocks. */ 00410 uint8_t data[512]; 00411 /** Used to access cached FAT16 entries. */ 00412 uint16_t fat16[256]; 00413 /** Used to access cached FAT32 entries. */ 00414 uint32_t fat32[128]; 00415 /** Used to access cached directory entries. */ 00416 dir_t dir[16]; 00417 /** Used to access a cached MasterBoot Record. */ 00418 mbr_t mbr; 00419 /** Used to access to a cached FAT boot sector. */ 00420 fbs_t fbs; 00421 }; 00422 //------------------------------------------------------------------------------ 00423 /** 00424 * \class SdVolume 00425 * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. 00426 */ 00427 class SdVolume { 00428 public: 00429 /** Create an instance of SdVolume */ 00430 SdVolume(void) :allocSearchStart_(2), fatType_(0) {} 00431 /** Clear the cache and returns a pointer to the cache. Used by the WaveRP 00432 * recorder to do raw write to the SD card. Not for normal apps. 00433 */ 00434 static uint8_t* cacheClear(void) { 00435 cacheFlush(); 00436 cacheBlockNumber_ = 0XFFFFFFFF; 00437 return cacheBuffer_.data; 00438 } 00439 /** 00440 * Initialize a FAT volume. Try partition one first then try super 00441 * floppy format. 00442 * 00443 * \param[in] dev The Sd2Card where the volume is located. 00444 * 00445 * \return The value one, true, is returned for success and 00446 * the value zero, false, is returned for failure. Reasons for 00447 * failure include not finding a valid partition, not finding a valid 00448 * FAT file system or an I/O error. 00449 */ 00450 uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} 00451 uint8_t init(Sd2Card* dev, uint8_t part); 00452 00453 // inline functions that return volume info 00454 /** \return The volume's cluster size in blocks. */ 00455 uint8_t blocksPerCluster (void) const {return blocksPerCluster_;} 00456 /** \return The number of blocks in one FAT. */ 00457 uint32_t blocksPerFat (void) const {return blocksPerFat_;} 00458 /** \return The total number of clusters in the volume. */ 00459 uint32_t clusterCount (void) const {return clusterCount_;} 00460 /** \return The shift count required to multiply by blocksPerCluster. */ 00461 uint8_t clusterSizeShift (void) const {return clusterSizeShift_;} 00462 /** \return The logical block number for the start of file data. */ 00463 uint32_t dataStartBlock (void) const {return dataStartBlock_;} 00464 /** \return The number of FAT structures on the volume. */ 00465 uint8_t fatCount (void) const {return fatCount_;} 00466 /** \return The logical block number for the start of the first FAT. */ 00467 uint32_t fatStartBlock (void) const {return fatStartBlock_;} 00468 /** \return The FAT type of the volume. Values are 12, 16 or 32. */ 00469 uint8_t fatType (void) const {return fatType_;} 00470 /** \return The number of entries in the root directory for FAT16 volumes. */ 00471 uint32_t rootDirEntryCount (void) const {return rootDirEntryCount_;} 00472 /** \return The logical block number for the start of the root directory 00473 on FAT16 volumes or the first cluster number on FAT32 volumes. */ 00474 uint32_t rootDirStart (void) const {return rootDirStart_;} 00475 /** return a pointer to the Sd2Card object for this volume */ 00476 static Sd2Card* sdCard(void) {return sdCard_;} 00477 //------------------------------------------------------------------------------ 00478 #if ALLOW_DEPRECATED_FUNCTIONS 00479 // Deprecated functions - suppress cpplint warnings with NOLINT comment 00480 /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ 00481 uint8_t init (Sd2Card& dev) {return init (&dev);} // NOLINT 00482 00483 /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ 00484 uint8_t init (Sd2Card& dev, uint8_t part) { // NOLINT 00485 return init(&dev, part); 00486 } 00487 #endif // ALLOW_DEPRECATED_FUNCTIONS 00488 //------------------------------------------------------------------------------ 00489 private: 00490 // Allow SdFile access to SdVolume private data. 00491 friend class SdFile; 00492 00493 // value for action argument in cacheRawBlock to indicate read from cache 00494 static uint8_t const CACHE_FOR_READ = 0; 00495 // value for action argument in cacheRawBlock to indicate cache dirty 00496 static uint8_t const CACHE_FOR_WRITE = 1; 00497 00498 static cache_t cacheBuffer_; // 512 byte cache for device blocks 00499 static uint32_t cacheBlockNumber_; // Logical number of block in the cache 00500 static Sd2Card* sdCard_; // Sd2Card object for cache 00501 static uint8_t cacheDirty_; // cacheFlush() will write block if true 00502 static uint32_t cacheMirrorBlock_; // block number for mirror FAT 00503 // 00504 uint32_t allocSearchStart_; // start cluster for alloc search 00505 uint8_t blocksPerCluster_; // cluster size in blocks 00506 uint32_t blocksPerFat_; // FAT size in blocks 00507 uint32_t clusterCount_; // clusters in one FAT 00508 uint8_t clusterSizeShift_; // shift to convert cluster count to block count 00509 uint32_t dataStartBlock_; // first data block number 00510 uint8_t fatCount_; // number of FATs on volume 00511 uint32_t fatStartBlock_; // start block for first FAT 00512 uint8_t fatType_; // volume type (12, 16, OR 32) 00513 uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir 00514 uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 00515 //---------------------------------------------------------------------------- 00516 uint8_t allocContiguous(uint32_t count, uint32_t* curCluster ); 00517 uint8_t blockOfCluster(uint32_t position) const { 00518 return (position >> 9) & (blocksPerCluster_ - 1);} 00519 uint32_t clusterStartBlock(uint32_t cluster) const { 00520 return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} 00521 uint32_t blockNumber(uint32_t cluster, uint32_t position) const { 00522 return clusterStartBlock(cluster) + blockOfCluster(position);} 00523 static uint8_t cacheFlush(void); 00524 static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); 00525 static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} 00526 static uint8_t cacheZeroBlock(uint32_t blockNumber); 00527 uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; 00528 uint8_t fatGet(uint32_t cluster, uint32_t* value) const; 00529 uint8_t fatPut(uint32_t cluster, uint32_t value); 00530 uint8_t fatPutEOC(uint32_t cluster) { 00531 return fatPut(cluster, 0x0FFFFFFF); 00532 } 00533 uint8_t freeChain(uint32_t cluster); 00534 uint8_t isEOC(uint32_t cluster) const { 00535 return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); 00536 } 00537 uint8_t readBlock(uint32_t block, uint8_t* dst) { 00538 return sdCard_->readBlock(block, dst);} 00539 uint8_t readData(uint32_t block, uint16_t offset, 00540 uint16_t count, uint8_t* dst) { 00541 return sdCard_->readData(block, offset, count, dst); 00542 } 00543 uint8_t writeBlock(uint32_t block, const uint8_t* dst) { 00544 return sdCard_->writeBlock(block, dst); 00545 } 00546 }; 00547 #endif // SdFat_h
Generated on Thu Jul 14 2022 02:07:54 by
1.7.2