SdFat.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /**
  2. * Copyright (c) 2011-2018 Bill Greiman
  3. * This file is part of the SdFat library for SD memory cards.
  4. *
  5. * MIT License
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef SdFat_h
  26. #define SdFat_h
  27. /**
  28. * \file
  29. * \brief SdFat class
  30. */
  31. #include "SysCall.h"
  32. #include "BlockDriver.h"
  33. #include "FatLib/FatLib.h"
  34. #include "SdCard/SdioCard.h"
  35. #if INCLUDE_SDIOS
  36. #include "sdios.h"
  37. #endif // INCLUDE_SDIOS
  38. //------------------------------------------------------------------------------
  39. /** SdFat version */
  40. #define SD_FAT_VERSION "1.0.13"
  41. //==============================================================================
  42. /**
  43. * \class SdBaseFile
  44. * \brief Class for backward compatibility.
  45. */
  46. class SdBaseFile : public FatFile {
  47. public:
  48. SdBaseFile() {}
  49. /** Create a file object and open it in the current working directory.
  50. *
  51. * \param[in] path A path for a file to be opened.
  52. *
  53. * \param[in] oflag Values for \a oflag are constructed by a
  54. * bitwise-inclusive OR of open flags. see
  55. * FatFile::open(FatFile*, const char*, oflag_t).
  56. */
  57. SdBaseFile(const char* path, oflag_t oflag) : FatFile(path, oflag) {}
  58. };
  59. //-----------------------------------------------------------------------------
  60. #if ENABLE_ARDUINO_FEATURES
  61. /**
  62. * \class SdFile
  63. * \brief Class for backward compatibility.
  64. */
  65. class SdFile : public PrintFile {
  66. public:
  67. SdFile() {}
  68. /** Create a file object and open it in the current working directory.
  69. *
  70. * \param[in] path A path for a file to be opened.
  71. *
  72. * \param[in] oflag Values for \a oflag are constructed by a
  73. * bitwise-inclusive OR of open flags. see
  74. * FatFile::open(FatFile*, const char*, oflag_t).
  75. */
  76. SdFile(const char* path, oflag_t oflag) : PrintFile(path, oflag) {}
  77. };
  78. #endif // #if ENABLE_ARDUINO_FEATURES
  79. //-----------------------------------------------------------------------------
  80. /**
  81. * \class SdFileSystem
  82. * \brief Virtual base class for %SdFat library.
  83. */
  84. template<class SdDriverClass>
  85. class SdFileSystem : public FatFileSystem {
  86. public:
  87. /** Initialize file system.
  88. * \return true for success else false.
  89. */
  90. bool begin() {
  91. return FatFileSystem::begin(&m_card);
  92. }
  93. /** \return Pointer to SD card object */
  94. SdDriverClass *card() {
  95. m_card.syncBlocks();
  96. return &m_card;
  97. }
  98. /** %Print any SD error code to Serial and halt. */
  99. void errorHalt() {
  100. errorHalt(&Serial);
  101. }
  102. /** %Print any SD error code and halt.
  103. *
  104. * \param[in] pr Print destination.
  105. */
  106. void errorHalt(Print* pr) {
  107. errorPrint(pr);
  108. SysCall::halt();
  109. }
  110. /** %Print msg, any SD error code and halt.
  111. *
  112. * \param[in] msg Message to print.
  113. */
  114. void errorHalt(char const* msg) {
  115. errorHalt(&Serial, msg);
  116. }
  117. /** %Print msg, any SD error code, and halt.
  118. *
  119. * \param[in] pr Print destination.
  120. * \param[in] msg Message to print.
  121. */
  122. void errorHalt(Print* pr, char const* msg) {
  123. errorPrint(pr, msg);
  124. SysCall::halt();
  125. }
  126. /** %Print any SD error code to Serial */
  127. void errorPrint() {
  128. errorPrint(&Serial);
  129. }
  130. /** %Print any SD error code.
  131. * \param[in] pr Print device.
  132. */
  133. void errorPrint(Print* pr) {
  134. if (!cardErrorCode()) {
  135. return;
  136. }
  137. pr->print(F("SD errorCode: 0X"));
  138. pr->print(cardErrorCode(), HEX);
  139. pr->print(F(",0X"));
  140. pr->println(cardErrorData(), HEX);
  141. }
  142. /** %Print msg, any SD error code.
  143. *
  144. * \param[in] msg Message to print.
  145. */
  146. void errorPrint(const char* msg) {
  147. errorPrint(&Serial, msg);
  148. }
  149. /** %Print msg, any SD error code.
  150. *
  151. * \param[in] pr Print destination.
  152. * \param[in] msg Message to print.
  153. */
  154. void errorPrint(Print* pr, char const* msg) {
  155. pr->print(F("error: "));
  156. pr->println(msg);
  157. errorPrint(pr);
  158. }
  159. /** %Print any SD error code and halt. */
  160. void initErrorHalt() {
  161. initErrorHalt(&Serial);
  162. }
  163. /** %Print error details and halt after begin fails.
  164. *
  165. * \param[in] pr Print destination.
  166. */
  167. void initErrorHalt(Print* pr) {
  168. initErrorPrint(pr);
  169. SysCall::halt();
  170. }
  171. /**Print message, error details, and halt after begin() fails.
  172. *
  173. * \param[in] msg Message to print.
  174. */
  175. void initErrorHalt(char const *msg) {
  176. initErrorHalt(&Serial, msg);
  177. }
  178. /**Print message, error details, and halt after begin() fails.
  179. * \param[in] pr Print device.
  180. * \param[in] msg Message to print.
  181. */
  182. void initErrorHalt(Print* pr, char const *msg) {
  183. pr->println(msg);
  184. initErrorHalt(pr);
  185. }
  186. /** Print error details after begin() fails. */
  187. void initErrorPrint() {
  188. initErrorPrint(&Serial);
  189. }
  190. /** Print error details after begin() fails.
  191. *
  192. * \param[in] pr Print destination.
  193. */
  194. void initErrorPrint(Print* pr) {
  195. if (cardErrorCode()) {
  196. pr->println(F("Can't access SD card. Do not reformat."));
  197. if (cardErrorCode() == SD_CARD_ERROR_CMD0) {
  198. pr->println(F("No card, wrong chip select pin, or SPI problem?"));
  199. }
  200. errorPrint(pr);
  201. } else if (vol()->fatType() == 0) {
  202. pr->println(F("Invalid format, reformat SD."));
  203. } else if (!vwd()->isOpen()) {
  204. pr->println(F("Can't open root directory."));
  205. } else {
  206. pr->println(F("No error found."));
  207. }
  208. }
  209. /**Print message and error details and halt after begin() fails.
  210. *
  211. * \param[in] msg Message to print.
  212. */
  213. void initErrorPrint(char const *msg) {
  214. initErrorPrint(&Serial, msg);
  215. }
  216. /**Print message and error details and halt after begin() fails.
  217. *
  218. * \param[in] pr Print destination.
  219. * \param[in] msg Message to print.
  220. */
  221. void initErrorPrint(Print* pr, char const *msg) {
  222. pr->println(msg);
  223. initErrorPrint(pr);
  224. }
  225. #if defined(ARDUINO) || defined(DOXYGEN)
  226. /** %Print msg, any SD error code, and halt.
  227. *
  228. * \param[in] msg Message to print.
  229. */
  230. void errorHalt(const __FlashStringHelper* msg) {
  231. errorHalt(&Serial, msg);
  232. }
  233. /** %Print msg, any SD error code, and halt.
  234. *
  235. * \param[in] pr Print destination.
  236. * \param[in] msg Message to print.
  237. */
  238. void errorHalt(Print* pr, const __FlashStringHelper* msg) {
  239. errorPrint(pr, msg);
  240. SysCall::halt();
  241. }
  242. /** %Print msg, any SD error code.
  243. *
  244. * \param[in] msg Message to print.
  245. */
  246. void errorPrint(const __FlashStringHelper* msg) {
  247. errorPrint(&Serial, msg);
  248. }
  249. /** %Print msg, any SD error code.
  250. *
  251. * \param[in] pr Print destination.
  252. * \param[in] msg Message to print.
  253. */
  254. void errorPrint(Print* pr, const __FlashStringHelper* msg) {
  255. pr->print(F("error: "));
  256. pr->println(msg);
  257. errorPrint(pr);
  258. }
  259. /**Print message, error details, and halt after begin() fails.
  260. *
  261. * \param[in] msg Message to print.
  262. */
  263. void initErrorHalt(const __FlashStringHelper* msg) {
  264. initErrorHalt(&Serial, msg);
  265. }
  266. /**Print message, error details, and halt after begin() fails.
  267. * \param[in] pr Print device for message.
  268. * \param[in] msg Message to print.
  269. */
  270. void initErrorHalt(Print* pr, const __FlashStringHelper* msg) {
  271. pr->println(msg);
  272. initErrorHalt(pr);
  273. }
  274. /**Print message and error details and halt after begin() fails.
  275. *
  276. * \param[in] msg Message to print.
  277. */
  278. void initErrorPrint(const __FlashStringHelper* msg) {
  279. initErrorPrint(&Serial, msg);
  280. }
  281. /**Print message and error details and halt after begin() fails.
  282. *
  283. * \param[in] pr Print destination.
  284. * \param[in] msg Message to print.
  285. */
  286. void initErrorPrint(Print* pr, const __FlashStringHelper* msg) {
  287. pr->println(msg);
  288. initErrorPrint(pr);
  289. }
  290. #endif // defined(ARDUINO) || defined(DOXYGEN)
  291. /** \return The card error code */
  292. uint8_t cardErrorCode() {
  293. return m_card.errorCode();
  294. }
  295. /** \return the card error data */
  296. uint32_t cardErrorData() {
  297. return m_card.errorData();
  298. }
  299. protected:
  300. SdDriverClass m_card;
  301. };
  302. //==============================================================================
  303. /**
  304. * \class SdFat
  305. * \brief Main file system class for %SdFat library.
  306. */
  307. class SdFat : public SdFileSystem<SdSpiCard> {
  308. public:
  309. #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN)
  310. SdFat() {
  311. m_spi.setPort(nullptr);
  312. }
  313. /** Constructor with SPI port selection.
  314. * \param[in] spiPort SPI port number.
  315. */
  316. explicit SdFat(SPIClass* spiPort) {
  317. m_spi.setPort(spiPort);
  318. }
  319. #endif // IMPLEMENT_SPI_PORT_SELECTION
  320. /** Initialize SD card and file system.
  321. *
  322. * \param[in] csPin SD card chip select pin.
  323. * \param[in] spiSettings SPI speed, mode, and bit order.
  324. * \return true for success else false.
  325. */
  326. bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) {
  327. return m_card.begin(&m_spi, csPin, spiSettings) &&
  328. SdFileSystem::begin();
  329. }
  330. /** Initialize SD card for diagnostic use only.
  331. *
  332. * \param[in] csPin SD card chip select pin.
  333. * \param[in] settings SPI speed, mode, and bit order.
  334. * \return true for success else false.
  335. */
  336. bool cardBegin(uint8_t csPin = SS, SPISettings settings = SPI_FULL_SPEED) {
  337. return m_card.begin(&m_spi, csPin, settings);
  338. }
  339. /** Initialize file system for diagnostic use only.
  340. * \return true for success else false.
  341. */
  342. bool fsBegin() {
  343. return FatFileSystem::begin(card());
  344. }
  345. private:
  346. SdFatSpiDriver m_spi;
  347. };
  348. //==============================================================================
  349. #if ENABLE_SDIO_CLASS || defined(DOXYGEN)
  350. /**
  351. * \class SdFatSdio
  352. * \brief SdFat class using SDIO.
  353. */
  354. class SdFatSdio : public SdFileSystem<SdioCard> {
  355. public:
  356. /** Initialize SD card and file system.
  357. * \return true for success else false.
  358. */
  359. bool begin() {
  360. return m_card.begin() && SdFileSystem::begin();
  361. }
  362. /** Initialize SD card for diagnostic use only.
  363. *
  364. * \return true for success else false.
  365. */
  366. bool cardBegin() {
  367. return m_card.begin();
  368. }
  369. /** Initialize file system for diagnostic use only.
  370. * \return true for success else false.
  371. */
  372. bool fsBegin() {
  373. return SdFileSystem::begin();
  374. }
  375. };
  376. #if ENABLE_SDIOEX_CLASS || defined(DOXYGEN)
  377. //-----------------------------------------------------------------------------
  378. /**
  379. * \class SdFatSdioEX
  380. * \brief SdFat class using SDIO.
  381. */
  382. class SdFatSdioEX : public SdFileSystem<SdioCardEX> {
  383. public:
  384. /** Initialize SD card and file system.
  385. * \return true for success else false.
  386. */
  387. bool begin() {
  388. return m_card.begin() && SdFileSystem::begin();
  389. }
  390. /** \return Pointer to SD card object */
  391. SdioCardEX* card() {
  392. return &m_card;
  393. }
  394. /** Initialize SD card for diagnostic use only.
  395. *
  396. * \return true for success else false.
  397. */
  398. bool cardBegin() {
  399. return m_card.begin();
  400. }
  401. /** Initialize file system for diagnostic use only.
  402. * \return true for success else false.
  403. */
  404. bool fsBegin() {
  405. return SdFileSystem::begin();
  406. }
  407. };
  408. #endif // ENABLE_SDIOEX_CLASS || defined(DOXYGEN)
  409. #endif // ENABLE_SDIO_CLASS || defined(DOXYGEN)
  410. //=============================================================================
  411. #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN)
  412. /**
  413. * \class SdFatSoftSpi
  414. * \brief SdFat class using software SPI.
  415. */
  416. template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
  417. class SdFatSoftSpi : public SdFileSystem<SdSpiCard> {
  418. public:
  419. /** Initialize SD card and file system.
  420. *
  421. * \param[in] csPin SD card chip select pin.
  422. * \param[in] spiSettings ignored for software SPI..
  423. * \return true for success else false.
  424. */
  425. bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) {
  426. return m_card.begin(&m_spi, csPin, spiSettings) &&
  427. SdFileSystem::begin();
  428. }
  429. private:
  430. SdSpiSoftDriver<MisoPin, MosiPin, SckPin> m_spi;
  431. };
  432. #endif // #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN)
  433. //==============================================================================
  434. #if ENABLE_EXTENDED_TRANSFER_CLASS || defined(DOXYGEN)
  435. /**
  436. * \class SdFatEX
  437. * \brief SdFat class with extended SD I/O.
  438. */
  439. class SdFatEX : public SdFileSystem<SdSpiCardEX> {
  440. public:
  441. #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN)
  442. SdFatEX() {
  443. m_spi.setPort(nullptr);
  444. }
  445. /** Constructor with SPI port selection.
  446. * \param[in] spiPort SPI port number.
  447. */
  448. explicit SdFatEX(SPIClass* spiPort) {
  449. m_spi.setPort(spiPort);
  450. }
  451. #endif // IMPLEMENT_SPI_PORT_SELECTION
  452. /** Initialize SD card and file system.
  453. *
  454. * \param[in] csPin SD card chip select pin.
  455. * \param[in] spiSettings SPI speed, mode, and bit order.
  456. * \return true for success else false.
  457. */
  458. bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) {
  459. return m_card.begin(&m_spi, csPin, spiSettings) &&
  460. SdFileSystem::begin();
  461. }
  462. private:
  463. SdFatSpiDriver m_spi;
  464. };
  465. //==============================================================================
  466. #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN)
  467. /**
  468. * \class SdFatSoftSpiEX
  469. * \brief SdFat class using software SPI and extended SD I/O.
  470. */
  471. template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
  472. class SdFatSoftSpiEX : public SdFileSystem<SdSpiCardEX> {
  473. public:
  474. /** Initialize SD card and file system.
  475. *
  476. * \param[in] csPin SD card chip select pin.
  477. * \param[in] spiSettings ignored for software SPI.
  478. * \return true for success else false.
  479. */
  480. bool begin(uint8_t csPin = SS, SPISettings spiSettings = SPI_FULL_SPEED) {
  481. return m_card.begin(&m_spi, csPin, spiSettings) &&
  482. SdFileSystem::begin();
  483. }
  484. private:
  485. SdSpiSoftDriver<MisoPin, MosiPin, SckPin> m_spi;
  486. };
  487. #endif // #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN)
  488. #endif // ENABLE_EXTENDED_TRANSFER_CLASS || defined(DOXYGEN)
  489. //=============================================================================
  490. /**
  491. * \class Sd2Card
  492. * \brief Raw access to SD and SDHC card using default SPI library.
  493. */
  494. class Sd2Card : public SdSpiCard {
  495. public:
  496. /** Initialize the SD card.
  497. * \param[in] csPin SD chip select pin.
  498. * \param[in] settings SPI speed, mode, and bit order.
  499. * \return true for success else false.
  500. */
  501. bool begin(uint8_t csPin = SS, SPISettings settings = SD_SCK_MHZ(50)) {
  502. return SdSpiCard::begin(&m_spi, csPin, settings);
  503. }
  504. private:
  505. SdFatSpiDriver m_spi;
  506. };
  507. #endif // SdFat_h