utility

Dependents:   SD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SdFat.h Source File

SdFat.h

Go to the documentation of this file.
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