SdFat.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /**
  2. * Copyright (c) 2011-2022 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 main SdFs include file.
  30. */
  31. #include "common/SysCall.h"
  32. #include "SdCard/SdCard.h"
  33. #include "ExFatLib/ExFatLib.h"
  34. #include "FatLib/FatLib.h"
  35. #include "FsLib/FsLib.h"
  36. #if INCLUDE_SDIOS
  37. #include "sdios.h"
  38. #endif // INCLUDE_SDIOS
  39. //------------------------------------------------------------------------------
  40. /** SdFat version for cpp use. */
  41. #define SD_FAT_VERSION 20200
  42. /** SdFat version as string. */
  43. #define SD_FAT_VERSION_STR "2.2.0"
  44. //==============================================================================
  45. /**
  46. * \class SdBase
  47. * \brief base SD file system template class.
  48. */
  49. template <class Vol, class Fmt>
  50. class SdBase : public Vol {
  51. public:
  52. //----------------------------------------------------------------------------
  53. /** Initialize SD card and file system.
  54. *
  55. * \param[in] csPin SD card chip select pin.
  56. * \return true for success or false for failure.
  57. */
  58. bool begin(SdCsPin_t csPin = SS) {
  59. #ifdef BUILTIN_SDCARD
  60. if (csPin == BUILTIN_SDCARD) {
  61. return begin(SdioConfig(FIFO_SDIO));
  62. }
  63. #endif // BUILTIN_SDCARD
  64. return begin(SdSpiConfig(csPin, SHARED_SPI));
  65. }
  66. //----------------------------------------------------------------------------
  67. /** Initialize SD card and file system.
  68. *
  69. * \param[in] csPin SD card chip select pin.
  70. * \param[in] maxSck Maximum SCK frequency.
  71. * \return true for success or false for failure.
  72. */
  73. bool begin(SdCsPin_t csPin, uint32_t maxSck) {
  74. return begin(SdSpiConfig(csPin, SHARED_SPI, maxSck));
  75. }
  76. //----------------------------------------------------------------------------
  77. /** Initialize SD card and file system for SPI mode.
  78. *
  79. * \param[in] spiConfig SPI configuration.
  80. * \return true for success or false for failure.
  81. */
  82. bool begin(SdSpiConfig spiConfig) {
  83. return cardBegin(spiConfig) && Vol::begin(m_card);
  84. }
  85. //---------------------------------------------------------------------------
  86. /** Initialize SD card and file system for SDIO mode.
  87. *
  88. * \param[in] sdioConfig SDIO configuration.
  89. * \return true for success or false for failure.
  90. */
  91. bool begin(SdioConfig sdioConfig) {
  92. return cardBegin(sdioConfig) && Vol::begin(m_card);
  93. }
  94. //----------------------------------------------------------------------------
  95. /** \return Pointer to SD card object. */
  96. SdCard* card() {return m_card;}
  97. //----------------------------------------------------------------------------
  98. /** Initialize SD card in SPI mode.
  99. *
  100. * \param[in] spiConfig SPI configuration.
  101. * \return true for success or false for failure.
  102. */
  103. bool cardBegin(SdSpiConfig spiConfig) {
  104. m_card = m_cardFactory.newCard(spiConfig);
  105. return m_card && !m_card->errorCode();
  106. }
  107. //----------------------------------------------------------------------------
  108. /** Initialize SD card in SDIO mode.
  109. *
  110. * \param[in] sdioConfig SDIO configuration.
  111. * \return true for success or false for failure.
  112. */
  113. bool cardBegin(SdioConfig sdioConfig) {
  114. m_card = m_cardFactory.newCard(sdioConfig);
  115. return m_card && !m_card->errorCode();
  116. }
  117. //----------------------------------------------------------------------------
  118. /** End use of card. */
  119. void end() {
  120. Vol::end();
  121. if (m_card) {
  122. m_card->end();
  123. }
  124. }
  125. //----------------------------------------------------------------------------
  126. /** %Print error info and halt.
  127. *
  128. * \param[in] pr Print destination.
  129. */
  130. void errorHalt(print_t* pr) {
  131. if (sdErrorCode()) {
  132. pr->print(F("SdError: 0X"));
  133. pr->print(sdErrorCode(), HEX);
  134. pr->print(F(",0X"));
  135. pr->println(sdErrorData(), HEX);
  136. } else if (!Vol::fatType()) {
  137. pr->println(F("Check SD format."));
  138. }
  139. while (true) {}
  140. }
  141. //----------------------------------------------------------------------------
  142. /** %Print error info and halt.
  143. *
  144. * \param[in] pr Print destination.
  145. * \param[in] msg Message to print.
  146. */
  147. void errorHalt(print_t* pr, const char* msg) {
  148. pr->print(F("error: "));
  149. pr->println(msg);
  150. errorHalt(pr);
  151. }
  152. //----------------------------------------------------------------------------
  153. /** %Print msg and halt.
  154. *
  155. * \param[in] pr Print destination.
  156. * \param[in] msg Message to print.
  157. */
  158. void errorHalt(print_t* pr, const __FlashStringHelper* msg) {
  159. pr->print(F("error: "));
  160. pr->println(msg);
  161. errorHalt(pr);
  162. }
  163. //----------------------------------------------------------------------------
  164. /** Format SD card
  165. *
  166. * \param[in] pr Print destination.
  167. * \return true for success else false.
  168. */
  169. bool format(print_t* pr = nullptr) {
  170. Fmt fmt;
  171. uint8_t* mem = Vol::end();
  172. if (!mem) {
  173. return false;
  174. }
  175. bool switchSpi = hasDedicatedSpi() && !isDedicatedSpi();
  176. if (switchSpi && !setDedicatedSpi(true)) {
  177. return false;
  178. }
  179. bool rtn = fmt.format(card(), mem, pr);
  180. if (switchSpi && !setDedicatedSpi(false)) {
  181. return false;
  182. }
  183. return rtn;
  184. }
  185. //----------------------------------------------------------------------------
  186. /** \return the free cluster count. */
  187. uint32_t freeClusterCount() {
  188. bool switchSpi = hasDedicatedSpi() && !isDedicatedSpi();
  189. if (switchSpi && !setDedicatedSpi(true)) {
  190. return 0;
  191. }
  192. uint32_t rtn = Vol::freeClusterCount();
  193. if (switchSpi && !setDedicatedSpi(false)) {
  194. return 0;
  195. }
  196. return rtn;
  197. }
  198. //----------------------------------------------------------------------------
  199. /** \return true if can be in dedicated SPI state */
  200. bool hasDedicatedSpi() {return m_card ? m_card->hasDedicatedSpi() : false;}
  201. //----------------------------------------------------------------------------
  202. /** %Print error info and halt.
  203. *
  204. * \param[in] pr Print destination.
  205. */
  206. void initErrorHalt(print_t* pr) {
  207. initErrorPrint(pr);
  208. while (true) {}
  209. }
  210. //----------------------------------------------------------------------------
  211. /** %Print error info and halt.
  212. *
  213. * \param[in] pr Print destination.
  214. * \param[in] msg Message to print.
  215. */
  216. void initErrorHalt(print_t* pr, const char* msg) {
  217. pr->println(msg);
  218. initErrorHalt(pr);
  219. }
  220. //----------------------------------------------------------------------------
  221. /** %Print error info and halt.
  222. *
  223. * \param[in] pr Print destination.
  224. * \param[in] msg Message to print.
  225. */
  226. void initErrorHalt(print_t* pr, const __FlashStringHelper* msg) {
  227. pr->println(msg);
  228. initErrorHalt(pr);
  229. }
  230. //----------------------------------------------------------------------------
  231. /** Print error details after begin() fails.
  232. *
  233. * \param[in] pr Print destination.
  234. */
  235. void initErrorPrint(print_t* pr) {
  236. pr->println(F("begin() failed"));
  237. if (sdErrorCode()) {
  238. pr->println(F("Do not reformat the SD."));
  239. if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
  240. pr->println(F("No card, wrong chip select pin, or wiring error?"));
  241. }
  242. }
  243. errorPrint(pr);
  244. }
  245. //----------------------------------------------------------------------------
  246. /** \return true if in dedicated SPI state. */
  247. bool isDedicatedSpi() {return m_card ? m_card->isDedicatedSpi() : false;}
  248. //----------------------------------------------------------------------------
  249. /** %Print volume FAT/exFAT type.
  250. *
  251. * \param[in] pr Print destination.
  252. */
  253. void printFatType(print_t* pr) {
  254. if (Vol::fatType() == FAT_TYPE_EXFAT) {
  255. pr->print(F("exFAT"));
  256. } else {
  257. pr->print(F("FAT"));
  258. pr->print(Vol::fatType());
  259. }
  260. }
  261. //----------------------------------------------------------------------------
  262. /** %Print SD errorCode and errorData.
  263. *
  264. * \param[in] pr Print destination.
  265. */
  266. void errorPrint(print_t* pr) {
  267. if (sdErrorCode()) {
  268. pr->print(F("SdError: 0X"));
  269. pr->print(sdErrorCode(), HEX);
  270. pr->print(F(",0X"));
  271. pr->println(sdErrorData(), HEX);
  272. } else if (!Vol::fatType()) {
  273. pr->println(F("Check SD format."));
  274. }
  275. }
  276. //----------------------------------------------------------------------------
  277. /** %Print msg, any SD error code.
  278. *
  279. * \param[in] pr Print destination.
  280. * \param[in] msg Message to print.
  281. */
  282. void errorPrint(print_t* pr, char const* msg) {
  283. pr->print(F("error: "));
  284. pr->println(msg);
  285. errorPrint(pr);
  286. }
  287. /** %Print msg, any SD error code.
  288. *
  289. * \param[in] pr Print destination.
  290. * \param[in] msg Message to print.
  291. */
  292. void errorPrint(print_t* pr, const __FlashStringHelper* msg) {
  293. pr->print(F("error: "));
  294. pr->println(msg);
  295. errorPrint(pr);
  296. }
  297. //----------------------------------------------------------------------------
  298. /** %Print error info and return.
  299. *
  300. * \param[in] pr Print destination.
  301. */
  302. void printSdError(print_t* pr) {
  303. if (sdErrorCode()) {
  304. if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
  305. pr->println(F("No card, wrong chip select pin, or wiring error?"));
  306. }
  307. pr->print(F("SD error: "));
  308. printSdErrorSymbol(pr, sdErrorCode());
  309. pr->print(F(" = 0x"));
  310. pr->print(sdErrorCode(), HEX);
  311. pr->print(F(",0x"));
  312. pr->println(sdErrorData(), HEX);
  313. } else if (!Vol::fatType()) {
  314. pr->println(F("Check SD format."));
  315. }
  316. }
  317. //----------------------------------------------------------------------------
  318. /** \return SD card error code. */
  319. uint8_t sdErrorCode() {
  320. if (m_card) {
  321. return m_card->errorCode();
  322. }
  323. return SD_CARD_ERROR_INVALID_CARD_CONFIG;
  324. }
  325. //----------------------------------------------------------------------------
  326. /** \return SD card error data. */
  327. uint8_t sdErrorData() {return m_card ? m_card->errorData() : 0;}
  328. //----------------------------------------------------------------------------
  329. /** Set SPI sharing state
  330. * \param[in] value desired state.
  331. * \return true for success else false;
  332. */
  333. bool setDedicatedSpi(bool value) {
  334. if (m_card) {
  335. return m_card->setDedicatedSpi(value);
  336. }
  337. return false;
  338. }
  339. //----------------------------------------------------------------------------
  340. /** \return pointer to base volume */
  341. Vol* vol() {return reinterpret_cast<Vol*>(this);}
  342. //----------------------------------------------------------------------------
  343. /** Initialize file system after call to cardBegin.
  344. *
  345. * \return true for success or false for failure.
  346. */
  347. bool volumeBegin() {
  348. return Vol::begin(m_card);
  349. }
  350. #if ENABLE_ARDUINO_SERIAL
  351. /** Print error details after begin() fails. */
  352. void initErrorPrint() {
  353. initErrorPrint(&Serial);
  354. }
  355. //----------------------------------------------------------------------------
  356. /** %Print msg to Serial and halt.
  357. *
  358. * \param[in] msg Message to print.
  359. */
  360. void errorHalt(const __FlashStringHelper* msg) {
  361. errorHalt(&Serial, msg);
  362. }
  363. //----------------------------------------------------------------------------
  364. /** %Print error info to Serial and halt. */
  365. void errorHalt() {errorHalt(&Serial);}
  366. //----------------------------------------------------------------------------
  367. /** %Print error info and halt.
  368. *
  369. * \param[in] msg Message to print.
  370. */
  371. void errorHalt(const char* msg) {errorHalt(&Serial, msg);}
  372. //----------------------------------------------------------------------------
  373. /** %Print error info and halt. */
  374. void initErrorHalt() {initErrorHalt(&Serial);}
  375. //----------------------------------------------------------------------------
  376. /** %Print msg, any SD error code.
  377. *
  378. * \param[in] msg Message to print.
  379. */
  380. void errorPrint(const char* msg) {errorPrint(&Serial, msg);}
  381. /** %Print msg, any SD error code.
  382. *
  383. * \param[in] msg Message to print.
  384. */
  385. void errorPrint(const __FlashStringHelper* msg) {errorPrint(&Serial, msg);}
  386. //----------------------------------------------------------------------------
  387. /** %Print error info and halt.
  388. *
  389. * \param[in] msg Message to print.
  390. */
  391. void initErrorHalt(const char* msg) {initErrorHalt(&Serial, msg);}
  392. //----------------------------------------------------------------------------
  393. /** %Print error info and halt.
  394. *
  395. * \param[in] msg Message to print.
  396. */
  397. void initErrorHalt(const __FlashStringHelper* msg) {
  398. initErrorHalt(&Serial, msg);
  399. }
  400. #endif // ENABLE_ARDUINO_SERIAL
  401. //----------------------------------------------------------------------------
  402. private:
  403. SdCard* m_card = nullptr;
  404. SdCardFactory m_cardFactory;
  405. };
  406. //------------------------------------------------------------------------------
  407. /**
  408. * \class SdFat32
  409. * \brief SD file system class for FAT volumes.
  410. */
  411. class SdFat32 : public SdBase<FatVolume, FatFormatter> {
  412. public:
  413. };
  414. //------------------------------------------------------------------------------
  415. /**
  416. * \class SdExFat
  417. * \brief SD file system class for exFAT volumes.
  418. */
  419. class SdExFat : public SdBase<ExFatVolume, ExFatFormatter> {
  420. public:
  421. };
  422. //------------------------------------------------------------------------------
  423. /**
  424. * \class SdFs
  425. * \brief SD file system class for FAT16, FAT32, and exFAT volumes.
  426. */
  427. class SdFs : public SdBase<FsVolume, FsFormatter> {
  428. public:
  429. };
  430. //------------------------------------------------------------------------------
  431. #if SDFAT_FILE_TYPE == 1 || defined(DOXYGEN)
  432. /** Select type for SdFat. */
  433. typedef SdFat32 SdFat;
  434. /** Select type for SdBaseFile. */
  435. typedef FatFile SdBaseFile;
  436. #elif SDFAT_FILE_TYPE == 2
  437. typedef SdExFat SdFat;
  438. typedef ExFatFile SdBaseFile;
  439. #elif SDFAT_FILE_TYPE == 3
  440. typedef SdFs SdFat;
  441. typedef FsBaseFile SdBaseFile;
  442. #else // SDFAT_FILE_TYPE
  443. #error Invalid SDFAT_FILE_TYPE
  444. #endif // SDFAT_FILE_TYPE
  445. //
  446. // Only define File if FS.h is not included.
  447. // Line with test for __has_include must not have operators or parentheses.
  448. #if defined __has_include
  449. #if __has_include(<FS.h>)
  450. #define HAS_INCLUDE_FS_H
  451. #warning File not defined because __has_include(FS.h)
  452. #endif // __has_include(<FS.h>)
  453. #endif // defined __has_include
  454. #ifndef HAS_INCLUDE_FS_H
  455. #if SDFAT_FILE_TYPE == 1 || defined(DOXYGEN)
  456. /** Select type for File. */
  457. typedef File32 File;
  458. #elif SDFAT_FILE_TYPE == 2
  459. typedef ExFile File;
  460. #elif SDFAT_FILE_TYPE == 3
  461. typedef FsFile File;
  462. #endif // SDFAT_FILE_TYPE
  463. #endif // HAS_INCLUDE_FS_H
  464. /**
  465. * \class SdFile
  466. * \brief FAT16/FAT32 file with Print.
  467. */
  468. class SdFile : public PrintFile<SdBaseFile> {
  469. public:
  470. SdFile() {}
  471. /** Create an open SdFile.
  472. * \param[in] path path for file.
  473. * \param[in] oflag open flags.
  474. */
  475. SdFile(const char* path, oflag_t oflag) {
  476. open(path, oflag);
  477. }
  478. /** Set the date/time callback function
  479. *
  480. * \param[in] dateTime The user's call back function. The callback
  481. * function is of the form:
  482. *
  483. * \code
  484. * void dateTime(uint16_t* date, uint16_t* time) {
  485. * uint16_t year;
  486. * uint8_t month, day, hour, minute, second;
  487. *
  488. * // User gets date and time from GPS or real-time clock here
  489. *
  490. * // return date using FS_DATE macro to format fields
  491. * *date = FS_DATE(year, month, day);
  492. *
  493. * // return time using FS_TIME macro to format fields
  494. * *time = FS_TIME(hour, minute, second);
  495. * }
  496. * \endcode
  497. *
  498. * Sets the function that is called when a file is created or when
  499. * a file's directory entry is modified by sync(). All timestamps,
  500. * access, creation, and modify, are set when a file is created.
  501. * sync() maintains the last access date and last modify date/time.
  502. *
  503. */
  504. static void dateTimeCallback(
  505. void (*dateTime)(uint16_t* date, uint16_t* time)) {
  506. FsDateTime::setCallback(dateTime);
  507. }
  508. /** Cancel the date/time callback function. */
  509. static void dateTimeCallbackCancel() {
  510. FsDateTime::clearCallback();
  511. }
  512. };
  513. #endif // SdFat_h