Repetier-Firmware  0.80
Repetier/SdFat.h
Go to the documentation of this file.
00001 /* Arduino SdFat Library
00002  * Copyright (C) 2012 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 /* Arduino SdFat Library
00021  * Copyright (C) 2012 by William Greiman
00022  *  
00023  * This file is part of the Arduino SdFat Library
00024  *  
00025  * This Library is free software: you can redistribute it and/or modify 
00026  * it under the terms of the GNU General Public License as published by 
00027  * the Free Software Foundation, either version 3 of the License, or
00028  * (at your option) any later version.
00029  * 
00030  * This Library is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00033  * GNU General Public License for more details.
00034  *
00035  * You should have received a copy of the GNU General Public License
00036  * along with the Arduino SdFat Library.  If not, see
00037  * <http://www.gnu.org/licenses/>.
00038  */
00039 
00247 #ifndef SdFat_h
00248 #define SdFat_h
00249 
00253 //------------------------------------------------------------------------------
00255 #define SD_FAT_VERSION 20120719
00256 //------------------------------------------------------------------------------
00258 #if !defined(ARDUINO) || ARDUINO < 100
00259 #error Arduino IDE must be 1.0 or greater
00260 #endif  // ARDUINO < 100
00261 //------------------------------------------------------------------------------
00262 #include <stdint.h>
00263 // Based on the document:
00264 //
00265 // SD Specifications
00266 // Part 1
00267 // Physical Layer
00268 // Simplified Specification
00269 // Version 3.01
00270 // May 18, 2010
00271 //
00272 // http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs
00273 //------------------------------------------------------------------------------
00274 // SD card commands
00276 uint8_t const CMD0 = 0X00;
00278 uint8_t const CMD8 = 0X08;
00280 uint8_t const CMD9 = 0X09;
00282 uint8_t const CMD10 = 0X0A;
00284 uint8_t const CMD12 = 0X0C;
00286 uint8_t const CMD13 = 0X0D;
00288 uint8_t const CMD17 = 0X11;
00290 uint8_t const CMD18 = 0X12;
00292 uint8_t const CMD24 = 0X18;
00294 uint8_t const CMD25 = 0X19;
00296 uint8_t const CMD32 = 0X20;
00299 uint8_t const CMD33 = 0X21;
00301 uint8_t const CMD38 = 0X26;
00303 uint8_t const CMD55 = 0X37;
00305 uint8_t const CMD58 = 0X3A;
00307 uint8_t const CMD59 = 0X3B;
00310 uint8_t const ACMD23 = 0X17;
00313 uint8_t const ACMD41 = 0X29;
00314 //------------------------------------------------------------------------------
00316 uint8_t const R1_READY_STATE = 0X00;
00318 uint8_t const R1_IDLE_STATE = 0X01;
00320 uint8_t const R1_ILLEGAL_COMMAND = 0X04;
00322 uint8_t const DATA_START_BLOCK = 0XFE;
00324 uint8_t const STOP_TRAN_TOKEN = 0XFD;
00326 uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC;
00328 uint8_t const DATA_RES_MASK = 0X1F;
00330 uint8_t const DATA_RES_ACCEPTED = 0X05;
00331 //------------------------------------------------------------------------------
00333 typedef struct CID {
00334   // byte 0
00336   unsigned char mid;
00337   // byte 1-2
00339   char oid[2];
00340   // byte 3-7
00342   char pnm[5];
00343   // byte 8
00345   unsigned char prv_m : 4;
00347   unsigned char prv_n : 4;
00348   // byte 9-12
00350   uint32_t psn;
00351   // byte 13
00353   unsigned char mdt_year_high : 4;
00355   unsigned char reserved : 4;
00356   // byte 14
00358   unsigned char mdt_month : 4;
00360   unsigned char mdt_year_low :4;
00361   // byte 15
00363   unsigned char always1 : 1;
00365   unsigned char crc : 7;
00366 }cid_t;
00367 //------------------------------------------------------------------------------
00369 typedef struct CSDV1 {
00370   // byte 0
00371   unsigned char reserved1 : 6;
00372   unsigned char csd_ver : 2;
00373   // byte 1
00374   unsigned char taac;
00375   // byte 2
00376   unsigned char nsac;
00377   // byte 3
00378   unsigned char tran_speed;
00379   // byte 4
00380   unsigned char ccc_high;
00381   // byte 5
00382   unsigned char read_bl_len : 4;
00383   unsigned char ccc_low : 4;
00384   // byte 6
00385   unsigned char c_size_high : 2;
00386   unsigned char reserved2 : 2;
00387   unsigned char dsr_imp : 1;
00388   unsigned char read_blk_misalign :1;
00389   unsigned char write_blk_misalign : 1;
00390   unsigned char read_bl_partial : 1;
00391   // byte 7
00392   unsigned char c_size_mid;
00393   // byte 8
00394   unsigned char vdd_r_curr_max : 3;
00395   unsigned char vdd_r_curr_min : 3;
00396   unsigned char c_size_low :2;
00397   // byte 9
00398   unsigned char c_size_mult_high : 2;
00399   unsigned char vdd_w_cur_max : 3;
00400   unsigned char vdd_w_curr_min : 3;
00401   // byte 10
00402   unsigned char sector_size_high : 6;
00403   unsigned char erase_blk_en : 1;
00404   unsigned char c_size_mult_low : 1;
00405   // byte 11
00406   unsigned char wp_grp_size : 7;
00407   unsigned char sector_size_low : 1;
00408   // byte 12
00409   unsigned char write_bl_len_high : 2;
00410   unsigned char r2w_factor : 3;
00411   unsigned char reserved3 : 2;
00412   unsigned char wp_grp_enable : 1;
00413   // byte 13
00414   unsigned char reserved4 : 5;
00415   unsigned char write_partial : 1;
00416   unsigned char write_bl_len_low : 2;
00417   // byte 14
00418   unsigned char reserved5: 2;
00419   unsigned char file_format : 2;
00420   unsigned char tmp_write_protect : 1;
00421   unsigned char perm_write_protect : 1;
00422   unsigned char copy : 1;
00424   unsigned char file_format_grp : 1;
00425   // byte 15
00426   unsigned char always1 : 1;
00427   unsigned char crc : 7;
00428 }csd1_t;
00429 //------------------------------------------------------------------------------
00431 typedef struct CSDV2 {
00432   // byte 0
00433   unsigned char reserved1 : 6;
00434   unsigned char csd_ver : 2;
00435   // byte 1
00437   unsigned char taac;
00438   // byte 2
00440   unsigned char nsac;
00441   // byte 3
00442   unsigned char tran_speed;
00443   // byte 4
00444   unsigned char ccc_high;
00445   // byte 5
00447   unsigned char read_bl_len : 4;
00448   unsigned char ccc_low : 4;
00449   // byte 6
00451   unsigned char reserved2 : 4;
00452   unsigned char dsr_imp : 1;
00454   unsigned char read_blk_misalign :1;
00456   unsigned char write_blk_misalign : 1;
00458   unsigned char read_bl_partial : 1;
00459   // byte 7
00461   unsigned char c_size_high : 6;
00463   unsigned char reserved3 : 2;
00464   // byte 8
00466   unsigned char c_size_mid;
00467   // byte 9
00469   unsigned char c_size_low;
00470   // byte 10
00472   unsigned char sector_size_high : 6;
00474   unsigned char erase_blk_en : 1;
00476   unsigned char reserved4 : 1;
00477   // byte 11
00478   unsigned char wp_grp_size : 7;
00480   unsigned char sector_size_low : 1;
00481   // byte 12
00483   unsigned char write_bl_len_high : 2;
00485   unsigned char r2w_factor : 3;
00487   unsigned char reserved5 : 2;
00489   unsigned char wp_grp_enable : 1;
00490   // byte 13
00491   unsigned char reserved6 : 5;
00493   unsigned char write_partial : 1;
00495   unsigned char write_bl_len_low : 2;
00496   // byte 14
00497   unsigned char reserved7: 2;
00499   unsigned char file_format : 2;
00500   unsigned char tmp_write_protect : 1;
00501   unsigned char perm_write_protect : 1;
00502   unsigned char copy : 1;
00504   unsigned char file_format_grp : 1;
00505   // byte 15
00507   unsigned char always1 : 1;
00509   unsigned char crc : 7;
00510 }csd2_t;
00511 //------------------------------------------------------------------------------
00513 union csd_t {
00514   csd1_t v1;
00515   csd2_t v2;
00516 };
00517 
00518 //------------------------------------------------------------------------------
00526 #define USE_SD_CRC 0
00527 //------------------------------------------------------------------------------
00535 #define USE_MULTIPLE_CARDS 0
00536 //------------------------------------------------------------------------------
00548 #define USE_SERIAL_FOR_STD_OUT 0
00549 //------------------------------------------------------------------------------
00567 #define ENDL_CALLS_FLUSH 0
00568 //------------------------------------------------------------------------------
00572 #define ALLOW_DEPRECATED_FUNCTIONS 1
00573 //------------------------------------------------------------------------------
00578 #define FAT12_SUPPORT 0
00579 //------------------------------------------------------------------------------
00584 #define SPI_SD_INIT_RATE 5
00585 //------------------------------------------------------------------------------
00590 #define SET_SPI_SS_HIGH 1
00591 //------------------------------------------------------------------------------
00601 #define MEGA_SOFT_SPI 0
00602 //------------------------------------------------------------------------------
00612 #define LEONARDO_SOFT_SPI 0
00613 //------------------------------------------------------------------------------
00617 #define USE_SOFTWARE_SPI 0
00618 // define software SPI pins so Mega can use unmodified 168/328 shields
00620 uint8_t const SOFT_SPI_CS_PIN = 10;
00622 uint8_t const SOFT_SPI_MOSI_PIN = 11;
00624 uint8_t const SOFT_SPI_MISO_PIN = 12;
00626 uint8_t const SOFT_SPI_SCK_PIN = 13;
00627 //------------------------------------------------------------------------------
00628 // SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
00630 uint8_t const SPI_FULL_SPEED = 0;
00632 uint8_t const SPI_HALF_SPEED = 1;
00634 uint8_t const SPI_QUARTER_SPEED = 2;
00636 uint8_t const SPI_EIGHTH_SPEED = 3;
00638 uint8_t const SPI_SIXTEENTH_SPEED = 4;
00639 //------------------------------------------------------------------------------
00641 uint16_t const SD_INIT_TIMEOUT = 2000;
00643 uint16_t const SD_ERASE_TIMEOUT = 10000;
00645 uint16_t const SD_READ_TIMEOUT = 300;
00647 uint16_t const SD_WRITE_TIMEOUT = 600;
00648 //------------------------------------------------------------------------------
00649 // SD card errors
00651 uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
00653 uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
00655 uint8_t const SD_CARD_ERROR_CMD12 = 0X3;
00657 uint8_t const SD_CARD_ERROR_CMD17 = 0X4;
00659 uint8_t const SD_CARD_ERROR_CMD18 = 0X5;
00661 uint8_t const SD_CARD_ERROR_CMD24 = 0X6;
00663 uint8_t const SD_CARD_ERROR_CMD25 = 0X7;
00665 uint8_t const SD_CARD_ERROR_CMD58 = 0X8;
00667 uint8_t const SD_CARD_ERROR_ACMD23 = 0X9;
00669 uint8_t const SD_CARD_ERROR_ACMD41 = 0XA;
00671 uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB;
00673 uint8_t const SD_CARD_ERROR_ERASE = 0XC;
00675 uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD;
00677 uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE;
00679 uint8_t const SD_CARD_ERROR_READ = 0XF;
00681 uint8_t const SD_CARD_ERROR_READ_REG = 0X10;
00683 uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11;
00685 uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12;
00687 uint8_t const SD_CARD_ERROR_WRITE = 0X13;
00689 uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14;  // REMOVE - not used
00691 uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15;
00693 uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16;
00695 uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17;
00697 uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
00699 uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
00701 uint8_t const SD_CARD_ERROR_CMD59 = 0X1A;
00703 uint8_t const SD_CARD_ERROR_READ_CRC = 0X1B;
00704 //------------------------------------------------------------------------------
00705 // card types
00707 uint8_t const SD_CARD_TYPE_SD1  = 1;
00709 uint8_t const SD_CARD_TYPE_SD2  = 2;
00711 uint8_t const SD_CARD_TYPE_SDHC = 3;
00715 //------------------------------------------------------------------------------
00716 #if LEONARDO_SOFT_SPI && defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY)
00717 #define SOFTWARE_SPI
00718 #elif MEGA_SOFT_SPI&&(defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
00719 #define SOFTWARE_SPI
00720 #elif USE_SOFTWARE_SPI
00721 #define SOFTWARE_SPI
00722 #endif  // LEONARDO_SOFT_SPI
00723 //------------------------------------------------------------------------------
00724 // define default chip select pin
00725 //
00726 #ifndef SOFTWARE_SPI
00727 // hardware pin defs
00729 uint8_t const  SD_CHIP_SELECT_PIN = SDSS;
00730 #else  // SOFTWARE_SPI
00731 
00732 uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN;
00733 #endif  // SOFTWARE_SPI
00734 //------------------------------------------------------------------------------
00739 class Sd2Card {
00740  public:
00742   Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
00743   uint32_t cardSize();
00744   bool erase(uint32_t firstBlock, uint32_t lastBlock);
00745   bool eraseSingleBlockEnable();
00750   void error(uint8_t code) {errorCode_ = code;}
00754   int errorCode() const {return errorCode_;}
00756   int errorData() const {return status_;}
00763   bool init(uint8_t sckRateID = SPI_FULL_SPEED,
00764     uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
00765   bool readBlock(uint32_t block, uint8_t* dst);
00775   bool readCID(cid_t* cid) {
00776     return readRegister(CMD10, cid);
00777   }
00786   bool readCSD(csd_t* csd) {
00787     return readRegister(CMD9, csd);
00788   }
00789   bool readData(uint8_t *dst);
00790   bool readStart(uint32_t blockNumber);
00791   bool readStop();
00792   bool setSckRate(uint8_t sckRateID);
00796   int type() const {return type_;}
00797   bool writeBlock(uint32_t blockNumber, const uint8_t* src);
00798   bool writeData(const uint8_t* src);
00799   bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
00800   bool writeStop();
00801 
00802  private:
00803   //----------------------------------------------------------------------------
00804   uint8_t chipSelectPin_;
00805   uint8_t errorCode_;
00806   uint8_t spiRate_;
00807   uint8_t status_;
00808   uint8_t type_;
00809   // private functions
00810   uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
00811     cardCommand(CMD55, 0);
00812     return cardCommand(cmd, arg);
00813   }
00814   uint8_t cardCommand(uint8_t cmd, uint32_t arg);
00815   bool readData(uint8_t* dst, uint16_t count);
00816   bool readRegister(uint8_t cmd, void* buf);
00817   void chipSelectHigh();
00818   void chipSelectLow();
00819   void type(uint8_t value) {type_ = value;}
00820   bool waitNotBusy(uint16_t timeoutMillis);
00821   bool writeData(uint8_t token, const uint8_t* src);
00822 };
00823 
00828 /*
00829  * mostly from Microsoft document fatgen103.doc
00830  * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
00831  */
00832 //------------------------------------------------------------------------------
00834 uint8_t const BOOTSIG0 = 0X55;
00836 uint8_t const BOOTSIG1 = 0XAA;
00838 uint8_t const EXTENDED_BOOT_SIG = 0X29;
00839 //------------------------------------------------------------------------------
00847 struct partitionTable {
00853   uint8_t  boot;
00858   uint8_t  beginHead;
00863   unsigned beginSector : 6;
00865   unsigned beginCylinderHigh : 2;
00870   uint8_t  beginCylinderLow;
00875   uint8_t  type;
00880   uint8_t  endHead;
00885   unsigned endSector : 6;
00887   unsigned endCylinderHigh : 2;
00892   uint8_t  endCylinderLow;
00894   uint32_t firstSector;
00896   uint32_t totalSectors;
00897 };
00899 typedef struct partitionTable part_t;
00900 //------------------------------------------------------------------------------
00908 struct masterBootRecord {
00910   uint8_t  codeArea[440];
00912   uint32_t diskSignature;
00914   uint16_t usuallyZero;
00916   part_t   part[4];
00918   uint8_t  mbrSig0;
00920   uint8_t  mbrSig1;
00921 };
00923 typedef struct masterBootRecord mbr_t;
00924 //------------------------------------------------------------------------------
00931 struct fat_boot {
00937   uint8_t jump[3];
00942   char    oemId[8];
00948   uint16_t bytesPerSector;
00954   uint8_t  sectorsPerCluster;
00959   uint16_t reservedSectorCount;
00964   uint8_t  fatCount;
00973   uint16_t rootDirEntryCount;
00983   uint16_t totalSectors16;
00990   uint8_t  mediaType;
00996   uint16_t sectorsPerFat16;
00998   uint16_t sectorsPerTrack;
01000   uint16_t headCount;
01006   uint32_t hidddenSectors;
01013   uint32_t totalSectors32;
01022   uint8_t  driveNumber;
01024   uint8_t  reserved1;
01026   uint8_t  bootSignature;
01032   uint32_t volumeSerialNumber;
01037   char     volumeLabel[11];
01042   char     fileSystemType[8];
01044   uint8_t  bootCode[448];
01046   uint8_t  bootSectorSig0;
01048   uint8_t  bootSectorSig1;
01049 };
01051 typedef struct fat_boot fat_boot_t;
01052 //------------------------------------------------------------------------------
01059 struct fat32_boot {
01065   uint8_t jump[3];
01070   char    oemId[8];
01076   uint16_t bytesPerSector;
01082   uint8_t  sectorsPerCluster;
01087   uint16_t reservedSectorCount;
01092   uint8_t  fatCount;
01096   uint16_t rootDirEntryCount;
01100   uint16_t totalSectors16;
01107   uint8_t  mediaType;
01112   uint16_t sectorsPerFat16;
01114   uint16_t sectorsPerTrack;
01116   uint16_t headCount;
01122   uint32_t hidddenSectors;
01126   uint32_t totalSectors32;
01130   uint32_t sectorsPerFat32;
01142   uint16_t fat32Flags;
01147   uint16_t fat32Version;
01152   uint32_t fat32RootCluster;
01157   uint16_t fat32FSInfo;
01163   uint16_t fat32BackBootBlock;
01168   uint8_t  fat32Reserved[12];
01177   uint8_t  driveNumber;
01179   uint8_t  reserved1;
01181   uint8_t  bootSignature;
01187   uint32_t volumeSerialNumber;
01192   char     volumeLabel[11];
01196   char     fileSystemType[8];
01198   uint8_t  bootCode[420];
01200   uint8_t  bootSectorSig0;
01202   uint8_t  bootSectorSig1;
01203 };
01205 typedef struct fat32_boot fat32_boot_t;
01206 //------------------------------------------------------------------------------
01208 uint32_t const FSINFO_LEAD_SIG = 0x41615252;
01210 uint32_t const FSINFO_STRUCT_SIG = 0x61417272;
01217 struct fat32_fsinfo {
01219   uint32_t  leadSignature;
01221   uint8_t  reserved1[480];
01223   uint32_t  structSignature;
01231   uint32_t freeCount;
01238   uint32_t nextFree;
01240   uint8_t  reserved2[12];
01242   uint8_t  tailSignature[4];
01243 };
01245 typedef struct fat32_fsinfo fat32_fsinfo_t;
01246 //------------------------------------------------------------------------------
01247 // End Of Chain values for FAT entries
01249 uint16_t const FAT12EOC = 0XFFF;
01251 uint16_t const FAT12EOC_MIN = 0XFF8;
01253 uint16_t const FAT16EOC = 0XFFFF;
01255 uint16_t const FAT16EOC_MIN = 0XFFF8;
01257 uint32_t const FAT32EOC = 0X0FFFFFFF;
01259 uint32_t const FAT32EOC_MIN = 0X0FFFFFF8;
01261 uint32_t const FAT32MASK = 0X0FFFFFFF;
01262 //------------------------------------------------------------------------------
01293 struct directoryEntry {
01299   uint8_t  name[11];
01306   uint8_t  attributes;
01311   uint8_t  reservedNT;
01317   uint8_t  creationTimeTenths;
01319   uint16_t creationTime;
01321   uint16_t creationDate;
01327   uint16_t lastAccessDate;
01332   uint16_t firstClusterHigh;
01334   uint16_t lastWriteTime;
01336   uint16_t lastWriteDate;
01338   uint16_t firstClusterLow;
01340   uint32_t fileSize;
01341 };
01342 //------------------------------------------------------------------------------
01343 // Definitions for directory entries
01344 //
01346 typedef struct directoryEntry dir_t;
01348 uint8_t const DIR_NAME_0XE5 = 0X05;
01350 uint8_t const DIR_NAME_DELETED = 0XE5;
01352 uint8_t const DIR_NAME_FREE = 0X00;
01354 uint8_t const DIR_ATT_READ_ONLY = 0X01;
01356 uint8_t const DIR_ATT_HIDDEN = 0X02;
01358 uint8_t const DIR_ATT_SYSTEM = 0X04;
01360 uint8_t const DIR_ATT_VOLUME_ID = 0X08;
01362 uint8_t const DIR_ATT_DIRECTORY = 0X10;
01364 uint8_t const DIR_ATT_ARCHIVE = 0X20;
01367 uint8_t const DIR_ATT_LONG_NAME = 0X0F;
01369 uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
01371 uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
01377 static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
01378   return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
01379 }
01381 uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
01387 static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
01388   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
01389 }
01395 static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
01396   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
01397 }
01403 static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
01404   return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
01405 }
01406 
01407 //==============================================================================
01408 // SdVolume class
01412 union cache_t {
01414   uint8_t  data[512];
01416   uint16_t fat16[256];
01418   uint32_t fat32[128];
01420   dir_t    dir[16];
01422   mbr_t    mbr;
01424   fat_boot_t fbs;
01426   fat32_boot_t fbs32;
01428   fat32_fsinfo_t fsinfo;
01429 };
01430 //------------------------------------------------------------------------------
01435 class SdVolume {
01436  public:
01438   SdVolume() : fatType_(0) {}
01443   cache_t* cacheClear() {
01444     if (!cacheFlush()) return 0;
01445     cacheBlockNumber_ = 0XFFFFFFFF;
01446     return &cacheBuffer_;
01447   }
01458   bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
01459   bool init(Sd2Card* dev, uint8_t part);
01460 
01461   // inline functions that return volume info
01463   uint8_t blocksPerCluster() const {return blocksPerCluster_;}
01465   uint32_t blocksPerFat()  const {return blocksPerFat_;}
01467   uint32_t clusterCount() const {return clusterCount_;}
01469   uint8_t clusterSizeShift() const {return clusterSizeShift_;}
01471   uint32_t dataStartBlock() const {return dataStartBlock_;}
01473   uint8_t fatCount() const {return fatCount_;}
01475   uint32_t fatStartBlock() const {return fatStartBlock_;}
01477   uint8_t fatType() const {return fatType_;}
01478   int32_t freeClusterCount();
01480   uint32_t rootDirEntryCount() const {return rootDirEntryCount_;}
01483   uint32_t rootDirStart() const {return rootDirStart_;}
01487   Sd2Card* sdCard() {return sdCard_;}
01494   bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);}
01495 //------------------------------------------------------------------------------
01496  private:
01497   // Allow SdBaseFile access to SdVolume private data.
01498   friend class SdBaseFile;
01499 
01500   // value for dirty argument in cacheRawBlock to indicate read from cache
01501   static bool const CACHE_FOR_READ = false;
01502   // value for dirty argument in cacheRawBlock to indicate write to cache
01503   static bool const CACHE_FOR_WRITE = true;
01504 
01505 #if USE_MULTIPLE_CARDS
01506   cache_t cacheBuffer_;        // 512 byte cache for device blocks
01507   uint32_t cacheBlockNumber_;  // Logical number of block in the cache
01508   Sd2Card* sdCard_;            // Sd2Card object for cache
01509   bool cacheDirty_;            // cacheFlush() will write block if true
01510   uint32_t cacheMirrorBlock_;  // block number for mirror FAT
01511 #else  // USE_MULTIPLE_CARDS
01512   static cache_t cacheBuffer_;        // 512 byte cache for device blocks
01513   static uint32_t cacheBlockNumber_;  // Logical number of block in the cache
01514   static Sd2Card* sdCard_;            // Sd2Card object for cache
01515   static bool cacheDirty_;            // cacheFlush() will write block if true
01516   static uint32_t cacheMirrorBlock_;  // block number for mirror FAT
01517 #endif  // USE_MULTIPLE_CARDS
01518   uint32_t allocSearchStart_;   // start cluster for alloc search
01519   uint8_t blocksPerCluster_;    // cluster size in blocks
01520   uint32_t blocksPerFat_;       // FAT size in blocks
01521   uint32_t clusterCount_;       // clusters in one FAT
01522   uint8_t clusterSizeShift_;    // shift to convert cluster count to block count
01523   uint32_t dataStartBlock_;     // first data block number
01524   uint8_t fatCount_;            // number of FATs on volume
01525   uint32_t fatStartBlock_;      // start block for first FAT
01526   uint8_t fatType_;             // volume type (12, 16, OR 32)
01527   uint16_t rootDirEntryCount_;  // number of entries in FAT16 root dir
01528   uint32_t rootDirStart_;       // root start block for FAT16, cluster for FAT32
01529   //----------------------------------------------------------------------------
01530   bool allocContiguous(uint32_t count, uint32_t* curCluster);
01531   uint8_t blockOfCluster(uint32_t position) const {
01532           return (position >> 9) & (blocksPerCluster_ - 1);}
01533   uint32_t clusterStartBlock(uint32_t cluster) const {
01534            return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);}
01535   cache_t *cache() {return &cacheBuffer_;}
01536   uint32_t cacheBlockNumber() {return cacheBlockNumber_;}
01537 #if USE_MULTIPLE_CARDS
01538   bool cacheFlush();
01539   bool cacheRawBlock(uint32_t blockNumber, bool dirty);
01540 #else  // USE_MULTIPLE_CARDS
01541   static bool cacheFlush();
01542   static bool cacheRawBlock(uint32_t blockNumber, bool dirty);
01543 #endif  // USE_MULTIPLE_CARDS
01544   // used by SdBaseFile write to assign cache to SD location
01545   void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) {
01546     cacheDirty_ = dirty;
01547     cacheBlockNumber_  = blockNumber;
01548   }
01549   void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;}
01550   bool chainSize(uint32_t beginCluster, uint32_t* size);
01551   bool fatGet(uint32_t cluster, uint32_t* value);
01552   bool fatPut(uint32_t cluster, uint32_t value);
01553   bool fatPutEOC(uint32_t cluster) {
01554     return fatPut(cluster, 0x0FFFFFFF);
01555   }
01556   bool freeChain(uint32_t cluster);
01557   bool isEOC(uint32_t cluster) const {
01558     if (FAT12_SUPPORT && fatType_ == 12) return  cluster >= FAT12EOC_MIN;
01559     if (fatType_ == 16) return cluster >= FAT16EOC_MIN;
01560     return  cluster >= FAT32EOC_MIN;
01561   }
01562   bool readBlock(uint32_t block, uint8_t* dst) {
01563     return sdCard_->readBlock(block, dst);}
01564   bool writeBlock(uint32_t block, const uint8_t* dst) {
01565     return sdCard_->writeBlock(block, dst);
01566   }
01567 //------------------------------------------------------------------------------
01568   // Deprecated functions  - suppress cpplint warnings with NOLINT comment
01569 #if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
01570 
01571  public:
01576   bool init(Sd2Card& dev) {return init(&dev);}  // NOLINT
01582   bool init(Sd2Card& dev, uint8_t part) {  // NOLINT
01583     return init(&dev, part);
01584   }
01585 #endif  // ALLOW_DEPRECATED_FUNCTIONS
01586 };
01587 
01588 //------------------------------------------------------------------------------
01594 struct fpos_t {
01596   uint32_t position;
01598   uint32_t cluster;
01599   fpos_t() : position(0), cluster(0) {}
01600 };
01601 
01602 // use the gnu style oflag in open()
01604 uint8_t const O_READ = 0X01;
01606 uint8_t const O_RDONLY = O_READ;
01608 uint8_t const O_WRITE = 0X02;
01610 uint8_t const O_WRONLY = O_WRITE;
01612 uint8_t const O_RDWR = (O_READ | O_WRITE);
01614 uint8_t const O_ACCMODE = (O_READ | O_WRITE);
01616 uint8_t const O_APPEND = 0X04;
01618 uint8_t const O_SYNC = 0X08;
01620 uint8_t const O_TRUNC = 0X10;
01622 uint8_t const O_AT_END = 0X20;
01624 uint8_t const O_CREAT = 0X40;
01626 uint8_t const O_EXCL = 0X80;
01627 
01628 // SdBaseFile class static and const definitions
01629 // flags for ls()
01631 uint8_t const LS_DATE = 1;
01633 uint8_t const LS_SIZE = 2;
01635 uint8_t const LS_R = 4;
01636 
01637 
01638 // flags for timestamp
01640 uint8_t const T_ACCESS = 1;
01642 uint8_t const T_CREATE = 2;
01644 uint8_t const T_WRITE = 4;
01645 // values for type_
01647 uint8_t const FAT_FILE_TYPE_CLOSED = 0;
01649 uint8_t const FAT_FILE_TYPE_NORMAL = 1;
01651 uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2;
01653 uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
01655 uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
01657 uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED;
01658 
01666 static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
01667   return (year - 1980) << 9 | month << 5 | day;
01668 }
01674 static inline uint16_t FAT_YEAR(uint16_t fatDate) {
01675   return 1980 + (fatDate >> 9);
01676 }
01682 static inline uint8_t FAT_MONTH(uint16_t fatDate) {
01683   return (fatDate >> 5) & 0XF;
01684 }
01690 static inline uint8_t FAT_DAY(uint16_t fatDate) {
01691   return fatDate & 0X1F;
01692 }
01700 static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
01701   return hour << 11 | minute << 5 | second >> 1;
01702 }
01708 static inline uint8_t FAT_HOUR(uint16_t fatTime) {
01709   return fatTime >> 11;
01710 }
01716 static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
01717   return(fatTime >> 5) & 0X3F;
01718 }
01726 static inline uint8_t FAT_SECOND(uint16_t fatTime) {
01727   return 2*(fatTime & 0X1F);
01728 }
01730 uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
01732 uint16_t const FAT_DEFAULT_TIME = (1 << 11);
01733 //------------------------------------------------------------------------------
01738 class SdBaseFile {
01739  public:
01741   SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
01742   SdBaseFile(const char* path, uint8_t oflag);
01743   ~SdBaseFile() {if(isOpen()) close();}
01749   bool writeError;
01751   bool getWriteError() {return writeError;}
01753   void clearWriteError() {writeError = 0;}
01754   //----------------------------------------------------------------------------
01755   // helpers for stream classes
01759   void getpos(fpos_t* pos);
01763   void setpos(fpos_t* pos);
01764   //----------------------------------------------------------------------------
01765   bool close();
01766   bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
01767   bool createContiguous(SdBaseFile* dirFile,
01768           const char* path, uint32_t size);
01770   uint32_t curCluster() const {return curCluster_;}
01772   uint32_t curPosition() const {return curPosition_;}
01774   static SdBaseFile* cwd() {return cwd_;}
01802   static void dateTimeCallback(
01803     void (*dateTime)(uint16_t* date, uint16_t* time)) {
01804     dateTime_ = dateTime;
01805   }
01807   static void dateTimeCallbackCancel() {dateTime_ = 0;}
01808   bool dirEntry(dir_t* dir);
01809   static void dirName(const dir_t& dir, char* name);
01810   bool exists(const char* name);
01811   int16_t fgets(char* str, int16_t num, char* delim = 0);
01813   uint32_t fileSize() const {return fileSize_;}
01815   uint32_t firstCluster() const {return firstCluster_;}
01816   bool getFilename(char* name);
01818   bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
01820   bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;}
01822   bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;}
01824   bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;}
01826   bool isRoot() const {
01827     return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32;
01828   }
01829   void ls(Print* pr, uint8_t flags = 0, uint8_t indent = 0);
01830   void ls(uint8_t flags = 0);
01831   bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
01832   // alias for backward compactability
01833   bool makeDir(SdBaseFile* dir, const char* path) {
01834     return mkdir(dir, path, false);
01835   }
01836   bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
01837   bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
01838   bool open(const char* path, uint8_t oflag = O_READ);
01839   bool openNext(SdBaseFile* dirFile, uint8_t oflag);
01840   bool openRoot(SdVolume* vol);
01841   int peek();
01842   bool printCreateDateTime(Print* pr);
01843   static void printFatDate(uint16_t fatDate);
01844   static void printFatDate(Print* pr, uint16_t fatDate);
01845   static void printFatTime(uint16_t fatTime);
01846   static void printFatTime(Print* pr, uint16_t fatTime);
01847   bool printModifyDateTime(Print* pr);
01848   bool printName();
01849   bool printName(Print* pr);
01850   int16_t read();
01851   int16_t read(void* buf, uint16_t nbyte);
01852   int8_t readDir(dir_t* dir);
01853   static bool remove(SdBaseFile* dirFile, const char* path);
01854   bool remove();
01856   void rewind() {seekSet(0);}
01857   bool rename(SdBaseFile* dirFile, const char* newPath);
01858   bool rmdir();
01859   // for backward compatibility
01860   bool rmDir() {return rmdir();}
01861   bool rmRfStar();
01866   bool seekCur(int32_t offset) {
01867     return seekSet(curPosition_ + offset);
01868   }
01873   bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);}
01874   bool seekSet(uint32_t pos);
01875   bool sync();
01876   bool timestamp(SdBaseFile* file);
01877   bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
01878           uint8_t hour, uint8_t minute, uint8_t second);
01884   uint8_t type() const {return type_;}
01885   bool truncate(uint32_t size);
01887   SdVolume* volume() const {return vol_;}
01888   int16_t write(const void* buf, uint16_t nbyte);
01889 //------------------------------------------------------------------------------
01890  public:
01891   // allow SdFat to set cwd_
01892   friend class SdFat;
01893   // global pointer to cwd dir
01894   static SdBaseFile* cwd_;
01895   // data time callback function
01896   static void (*dateTime_)(uint16_t* date, uint16_t* time);
01897   // bits defined in flags_
01898   // should be 0X0F
01899   static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
01900   // sync of directory entry required
01901   static uint8_t const F_FILE_DIR_DIRTY = 0X80;
01902 
01903   // private data
01904   uint8_t   flags_;         // See above for definition of flags_ bits
01905   uint8_t   fstate_;        // error and eof indicator
01906   uint8_t   type_;          // type of file see above for values
01907   uint32_t  curCluster_;    // cluster for current file position
01908   uint32_t  curPosition_;   // current file position in bytes from beginning
01909   uint32_t  dirBlock_;      // block for this files directory entry
01910   uint8_t   dirIndex_;      // index of directory entry in dirBlock
01911   uint32_t  fileSize_;      // file size in bytes
01912   uint32_t  firstCluster_;  // first cluster of file
01913   SdVolume* vol_;           // volume where file is located
01914 
01916   bool openParent(SdBaseFile* dir);
01917   // private functions
01918   bool addCluster();
01919   bool addDirCluster();
01920   dir_t* cacheDirEntry(uint8_t action);
01921   int8_t lsPrintNext(Print *pr, uint8_t flags, uint8_t indent);
01922   static bool make83Name(const char* str, uint8_t* name, const char** ptr);
01923   bool mkdir(SdBaseFile* parent, const uint8_t dname[11]);
01924   bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
01925   bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
01926   dir_t* readDirCache();
01927 //------------------------------------------------------------------------------
01928 // to be deleted
01929   static void printDirName(const dir_t& dir,
01930     uint8_t width, bool printSlash);
01931   static void printDirName(Print* pr, const dir_t& dir,
01932     uint8_t width, bool printSlash);
01933 //------------------------------------------------------------------------------
01934 // Deprecated functions  - suppress cpplint warnings with NOLINT comment
01935 #if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
01936 
01937  public:
01944   bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) {  // NOLINT
01945     return contiguousRange(&bgnBlock, &endBlock);
01946   }
01955   bool createContiguous(SdBaseFile& dirFile,  // NOLINT
01956     const char* path, uint32_t size) {
01957     return createContiguous(&dirFile, path, size);
01958   }
01964   static void dateTimeCallback(
01965     void (*dateTime)(uint16_t& date, uint16_t& time)) {  // NOLINT
01966     oldDateTime_ = dateTime;
01967     dateTime_ = dateTime ? oldToNew : 0;
01968   }
01973   bool dirEntry(dir_t& dir) {return dirEntry(&dir);}  // NOLINT
01981   bool mkdir(SdBaseFile& dir, const char* path) {  // NOLINT
01982     return mkdir(&dir, path);
01983   }
01993   bool open(SdBaseFile& dirFile, // NOLINT
01994     const char* path, uint8_t oflag) {
01995     return open(&dirFile, path, oflag);
01996   }
02003   bool open(SdBaseFile& dirFile, const char* path) {  // NOLINT
02004     return open(dirFile, path, O_RDWR);
02005   }
02015   bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) {  // NOLINT
02016     return open(&dirFile, index, oflag);
02017   }
02022   bool openRoot(SdVolume& vol) {return openRoot(&vol);}  // NOLINT
02027   int8_t readDir(dir_t& dir) {return readDir(&dir);}  // NOLINT
02034   static bool remove(SdBaseFile& dirFile, const char* path) {  // NOLINT
02035     return remove(&dirFile, path);
02036   }
02037 //------------------------------------------------------------------------------
02038 // rest are private
02039  private:
02040   static void (*oldDateTime_)(uint16_t& date, uint16_t& time);  // NOLINT
02041   static void oldToNew(uint16_t* date, uint16_t* time) {
02042     uint16_t d;
02043     uint16_t t;
02044     oldDateTime_(d, t);
02045     *date = d;
02046     *time = t;
02047   }
02048 #endif  // ALLOW_DEPRECATED_FUNCTIONS
02049 };
02050 //------------------------------------------------------------------------------
02055 class SdFile : public SdBaseFile, public Print {
02056  public:
02057   SdFile() {}
02058   SdFile(const char* name, uint8_t oflag);
02060   bool getWriteError() {return SdBaseFile::getWriteError();}
02062   void clearWriteError() {SdBaseFile::clearWriteError();}
02063   size_t write(uint8_t b);
02064   int16_t write(const char* str);
02065   int16_t write(const void* buf, uint16_t nbyte);
02066   void write_P(PGM_P str);
02067   void writeln_P(PGM_P str);
02068 };
02070 #define PgmPrint(x) SerialPrint_P(PSTR(x))
02071 
02072 #define PgmPrintln(x) SerialPrintln_P(PSTR(x))
02073 
02074 namespace SdFatUtil {
02075   int FreeRam();
02076   void print_P(Print* pr, PGM_P str);
02077   void println_P(Print* pr, PGM_P str);
02078   void SerialPrint_P(PGM_P str);
02079   void SerialPrintln_P(PGM_P str);
02080 }
02081 
02082 using namespace SdFatUtil;  // NOLINT
02083 
02084 //#include <SdStream.h>
02085 //#include <ArduinoStream.h>
02086 //------------------------------------------------------------------------------
02091 class SdFat {
02092  public:
02093   SdFat() {}
02105   bool begin(uint8_t chipSelectPin = SD_CHIP_SELECT_PIN,
02106     uint8_t sckRateID = SPI_FULL_SPEED) {
02107     return init(sckRateID, chipSelectPin);
02108   }
02110   Sd2Card* card() {return &card_;}
02111   bool chdir(bool set_cwd = false);
02112   bool chdir(const char* path, bool set_cwd = false);
02113   void chvol();
02114   void errorHalt();
02115   void errorHalt_P(PGM_P msg);
02116   void errorHalt(char const *msg);
02117   void errorPrint();
02118   void errorPrint_P(PGM_P msg);
02119   void errorPrint(char const *msg);
02120   bool exists(const char* name);
02121   bool init(uint8_t sckRateID = SPI_FULL_SPEED,
02122     uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
02123   void initErrorHalt();
02124   void initErrorHalt(char const *msg);
02125   void initErrorHalt_P(PGM_P msg);
02126   void initErrorPrint();
02127   void initErrorPrint(char const *msg);
02128   void initErrorPrint_P(PGM_P msg);
02129   void ls(uint8_t flags = 0);
02130   void ls(Print* pr, uint8_t flags = 0);
02131   bool mkdir(const char* path, bool pFlag = true);
02132   bool remove(const char* path);
02133   bool rename(const char *oldPath, const char *newPath);
02134   bool rmdir(const char* path);
02135   bool truncate(const char* path, uint32_t length);
02137   SdVolume* vol() {return &vol_;}
02139   SdBaseFile* vwd() {return &vwd_;}
02140   //----------------------------------------------------------------------------
02141   // static functions for stdOut
02146   static void setStdOut(Print* stream) {stdOut_ = stream;}
02148   static Print* stdOut() {return stdOut_;}
02149 
02150  private:
02151   Sd2Card card_;
02152   SdVolume vol_;
02153   SdBaseFile vwd_;
02154   static Print* stdOut_;
02155 };
02156 #endif  // SdFat_h
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Defines