You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

454 lines
14KB

  1. /**
  2. * Copyright (c) 2011-2019 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 */
  41. #define SD_FAT_VERSION "2.0.0"
  42. //==============================================================================
  43. /**
  44. * \class SdBase
  45. * \brief base SD file system template class.
  46. */
  47. template <class Vol>
  48. class SdBase : public Vol {
  49. public:
  50. //----------------------------------------------------------------------------
  51. /** Initialize SD card and file system.
  52. *
  53. * \param[in] csPin SD card chip select pin.
  54. * \return true for success or false for failure.
  55. */
  56. bool begin(uint8_t csPin = SS) {
  57. #ifdef BUILTIN_SDCARD
  58. if (csPin == BUILTIN_SDCARD) {
  59. return begin(SdioConfig(FIFO_SDIO));
  60. }
  61. #endif // BUILTIN_SDCARD
  62. return begin(SdSpiConfig(csPin, SHARED_SPI));
  63. }
  64. #if ENABLE_ARDUINO_FEATURES
  65. //----------------------------------------------------------------------------
  66. /** Initialize SD card and file system.
  67. *
  68. * \param[in] csPin SD card chip select pin.
  69. * \param[in] spiSettings SPI speed, mode, and bit order.
  70. * \return true for success or false for failure.
  71. */
  72. bool begin(uint8_t csPin, SPISettings spiSettings) {
  73. return begin(SdSpiConfig(csPin, SHARED_SPI, spiSettings));
  74. }
  75. #endif // ENABLE_ARDUINO_FEATURES
  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. /** %Print error info and halt.
  119. *
  120. * \param[in] pr Print destination.
  121. */
  122. void errorHalt(print_t* pr) {
  123. if (sdErrorCode()) {
  124. pr->print(F("SdError: 0X"));
  125. pr->print(sdErrorCode(), HEX);
  126. pr->print(F(",0X"));
  127. pr->println(sdErrorData(), HEX);
  128. } else if (!Vol::fatType()) {
  129. pr->println(F("Check SD format."));
  130. }
  131. SysCall::halt();
  132. }
  133. //----------------------------------------------------------------------------
  134. /** %Print error info and halt.
  135. *
  136. * \param[in] pr Print destination.
  137. * \param[in] msg Message to print.
  138. */
  139. void errorHalt(print_t* pr, const char* msg) {
  140. pr->print(F("error: "));
  141. pr->println(msg);
  142. errorHalt(pr);
  143. }
  144. //----------------------------------------------------------------------------
  145. /** %Print msg and halt.
  146. *
  147. * \param[in] pr Print destination.
  148. * \param[in] msg Message to print.
  149. */
  150. void errorHalt(print_t* pr, const __FlashStringHelper* msg) {
  151. pr->print(F("error: "));
  152. pr->println(msg);
  153. errorHalt(pr);
  154. }
  155. //----------------------------------------------------------------------------
  156. /** %Print error info and halt.
  157. *
  158. * \param[in] pr Print destination.
  159. */
  160. void initErrorHalt(print_t* pr) {
  161. initErrorPrint(pr);
  162. SysCall::halt();
  163. }
  164. //----------------------------------------------------------------------------
  165. /** %Print error info and halt.
  166. *
  167. * \param[in] pr Print destination.
  168. * \param[in] msg Message to print.
  169. */
  170. void initErrorHalt(print_t* pr, const char* msg) {
  171. pr->println(msg);
  172. initErrorHalt(pr);
  173. }
  174. //----------------------------------------------------------------------------
  175. /** %Print error info and halt.
  176. *
  177. * \param[in] pr Print destination.
  178. * \param[in] msg Message to print.
  179. */
  180. void initErrorHalt(Print* pr, const __FlashStringHelper* msg) {
  181. pr->println(msg);
  182. initErrorHalt(pr);
  183. }
  184. //----------------------------------------------------------------------------
  185. /** Print error details after begin() fails.
  186. *
  187. * \param[in] pr Print destination.
  188. */
  189. void initErrorPrint(Print* pr) {
  190. pr->println(F("begin() failed"));
  191. if (sdErrorCode()) {
  192. pr->println(F("Do not reformat the SD."));
  193. if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
  194. pr->println(F("No card, wrong chip select pin, or wiring error?"));
  195. }
  196. }
  197. errorPrint(pr);
  198. }
  199. //----------------------------------------------------------------------------
  200. /** %Print volume FAT/exFAT type.
  201. *
  202. * \param[in] pr Print destination.
  203. */
  204. void printFatType(print_t* pr) {
  205. if (Vol::fatType() == FAT_TYPE_EXFAT) {
  206. pr->print(F("exFAT"));
  207. } else {
  208. pr->print(F("FAT"));
  209. pr->print(Vol::fatType());
  210. }
  211. }
  212. //----------------------------------------------------------------------------
  213. /** %Print SD errorCode and errorData.
  214. *
  215. * \param[in] pr Print destination.
  216. */
  217. void errorPrint(print_t* pr) {
  218. if (sdErrorCode()) {
  219. pr->print(F("SdError: 0X"));
  220. pr->print(sdErrorCode(), HEX);
  221. pr->print(F(",0X"));
  222. pr->println(sdErrorData(), HEX);
  223. } else if (!Vol::fatType()) {
  224. pr->println(F("Check SD format."));
  225. }
  226. }
  227. //----------------------------------------------------------------------------
  228. /** %Print msg, any SD error code.
  229. *
  230. * \param[in] pr Print destination.
  231. * \param[in] msg Message to print.
  232. */
  233. void errorPrint(print_t* pr, char const* msg) {
  234. pr->print(F("error: "));
  235. pr->println(msg);
  236. errorPrint(pr);
  237. }
  238. /** %Print msg, any SD error code.
  239. *
  240. * \param[in] pr Print destination.
  241. * \param[in] msg Message to print.
  242. */
  243. void errorPrint(Print* pr, const __FlashStringHelper* msg) {
  244. pr->print(F("error: "));
  245. pr->println(msg);
  246. errorPrint(pr);
  247. }
  248. //----------------------------------------------------------------------------
  249. /** %Print error info and return.
  250. *
  251. * \param[in] pr Print destination.
  252. */
  253. void printSdError(print_t* pr) {
  254. if (sdErrorCode()) {
  255. if (sdErrorCode() == SD_CARD_ERROR_CMD0) {
  256. pr->println(F("No card, wrong chip select pin, or wiring error?"));
  257. }
  258. pr->print(F("SD error: "));
  259. printSdErrorSymbol(pr, sdErrorCode());
  260. pr->print(F(" = 0x"));
  261. pr->print(sdErrorCode(), HEX);
  262. pr->print(F(",0x"));
  263. pr->println(sdErrorData(), HEX);
  264. } else if (!Vol::cwv()) {
  265. pr->println(F("Check SD format."));
  266. }
  267. }
  268. //----------------------------------------------------------------------------
  269. /** \return SD card error code. */
  270. uint8_t sdErrorCode() {
  271. if (m_card) {
  272. return m_card->errorCode();
  273. }
  274. return SD_CARD_ERROR_INVALID_CARD_CONFIG;
  275. }
  276. //----------------------------------------------------------------------------
  277. /** \return SD card error data. */
  278. uint8_t sdErrorData() {return m_card ? m_card->errorData() : 0;}
  279. //----------------------------------------------------------------------------
  280. /** \return pointer to base volume */
  281. Vol* vol() {return reinterpret_cast<Vol*>(this);}
  282. //----------------------------------------------------------------------------
  283. /** Initialize file system after call to cardBegin.
  284. *
  285. * \return true for success or false for failure.
  286. */
  287. bool volumeBegin() {
  288. return Vol::begin(m_card);
  289. }
  290. #if ENABLE_ARDUINO_SERIAL
  291. /** Print error details after begin() fails. */
  292. void initErrorPrint() {
  293. initErrorPrint(&Serial);
  294. }
  295. //----------------------------------------------------------------------------
  296. /** %Print msg to Serial and halt.
  297. *
  298. * \param[in] msg Message to print.
  299. */
  300. void errorHalt(const __FlashStringHelper* msg) {
  301. errorHalt(&Serial, msg);
  302. }
  303. //----------------------------------------------------------------------------
  304. /** %Print error info to Serial and halt. */
  305. void errorHalt() {errorHalt(&Serial);}
  306. //----------------------------------------------------------------------------
  307. /** %Print error info and halt.
  308. *
  309. * \param[in] msg Message to print.
  310. */
  311. void errorHalt(const char* msg) {errorHalt(&Serial, msg);}
  312. //----------------------------------------------------------------------------
  313. /** %Print error info and halt. */
  314. void initErrorHalt() {initErrorHalt(&Serial);}
  315. //----------------------------------------------------------------------------
  316. /** %Print msg, any SD error code.
  317. *
  318. * \param[in] msg Message to print.
  319. */
  320. void errorPrint(const char* msg) {errorPrint(&Serial, msg);}
  321. /** %Print msg, any SD error code.
  322. *
  323. * \param[in] msg Message to print.
  324. */
  325. void errorPrint(const __FlashStringHelper* msg) {errorPrint(&Serial, msg);}
  326. //----------------------------------------------------------------------------
  327. void initErrorHalt(const char* msg) {initErrorHalt(&Serial, msg);}
  328. void initErrorHalt(const __FlashStringHelper* msg) {
  329. initErrorHalt(&Serial, msg);
  330. }
  331. #endif // ENABLE_ARDUINO_SERIAL
  332. //----------------------------------------------------------------------------
  333. private:
  334. SdCard* m_card;
  335. SdCardFactory m_cardFactory;
  336. };
  337. //------------------------------------------------------------------------------
  338. /**
  339. * \class SdFat32
  340. * \brief SD file system class for FAT volumes.
  341. */
  342. class SdFat32 : public SdBase<FatVolume> {
  343. public:
  344. /** Format a SD card FAT32/FAT16.
  345. *
  346. * \param[in] pr Optional Print information.
  347. * \return true for success or false for failure.
  348. */
  349. bool format(print_t* pr = nullptr) {
  350. FatFormatter fmt;
  351. uint8_t* cache = reinterpret_cast<uint8_t*>(cacheClear());
  352. if (!cache) {
  353. return false;
  354. }
  355. return fmt.format(card(), cache, pr);
  356. }
  357. };
  358. //------------------------------------------------------------------------------
  359. /**
  360. * \class SdExFat
  361. * \brief SD file system class for exFAT volumes.
  362. */
  363. class SdExFat : public SdBase<ExFatVolume> {
  364. public:
  365. /** Format a SD card exFAT.
  366. *
  367. * \param[in] pr Optional Print information.
  368. * \return true for success or false for failure.
  369. */
  370. bool format(print_t* pr = nullptr) {
  371. ExFatFormatter fmt;
  372. uint8_t* cache = reinterpret_cast<uint8_t*>(cacheClear());
  373. if (!cache) {
  374. return false;
  375. }
  376. return fmt.format(card(), cache, pr);
  377. }
  378. };
  379. //------------------------------------------------------------------------------
  380. /**
  381. * \class SdFs
  382. * \brief SD file system class for FAT16, FAT32, and exFAT volumes.
  383. */
  384. class SdFs : public SdBase<FsVolume> {
  385. };
  386. //------------------------------------------------------------------------------
  387. #if SDFAT_FILE_TYPE == 1
  388. typedef SdFat32 SdFat;
  389. typedef File32 File;
  390. typedef FatFile SdBaseFile;
  391. #elif SDFAT_FILE_TYPE == 2
  392. typedef SdExFat SdFat;
  393. typedef ExFile File;
  394. typedef ExFatFile SdBaseFile;
  395. #elif SDFAT_FILE_TYPE == 3
  396. typedef SdFs SdFat;
  397. typedef FsFile File;
  398. typedef FsBaseFile SdBaseFile;
  399. #else // SDFAT_FILE_TYPE
  400. #error Invalid SDFAT_FILE_TYPE
  401. #endif // SDFAT_FILE_TYPE
  402. /**
  403. * \class SdFile
  404. * \brief FAT16/FAT32 file with Print.
  405. */
  406. class SdFile : public PrintFile<SdBaseFile> {
  407. public:
  408. SdFile() {}
  409. /** Create an open SdFile.
  410. * \param[in] path path for file.
  411. * \param[in] oflag open flags.
  412. */
  413. SdFile(const char* path, oflag_t oflag) {
  414. open(path, oflag);
  415. }
  416. /** Set the date/time callback function
  417. *
  418. * \param[in] dateTime The user's call back function. The callback
  419. * function is of the form:
  420. *
  421. * \code
  422. * void dateTime(uint16_t* date, uint16_t* time) {
  423. * uint16_t year;
  424. * uint8_t month, day, hour, minute, second;
  425. *
  426. * // User gets date and time from GPS or real-time clock here
  427. *
  428. * // return date using FAT_DATE macro to format fields
  429. * *date = FAT_DATE(year, month, day);
  430. *
  431. * // return time using FAT_TIME macro to format fields
  432. * *time = FAT_TIME(hour, minute, second);
  433. * }
  434. * \endcode
  435. *
  436. * Sets the function that is called when a file is created or when
  437. * a file's directory entry is modified by sync(). All timestamps,
  438. * access, creation, and modify, are set when a file is created.
  439. * sync() maintains the last access date and last modify date/time.
  440. *
  441. */
  442. static void dateTimeCallback(
  443. void (*dateTime)(uint16_t* date, uint16_t* time)) {
  444. FsDateTime::setCallback(dateTime);
  445. }
  446. /** Cancel the date/time callback function. */
  447. static void dateTimeCallbackCancel() {
  448. FsDateTime::clearCallback();
  449. }
  450. };
  451. #endif // SdFat_h