![]() |
Repetier-Firmware
0.80
|
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