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.

313 lines
9.8KB

  1. /* Arduino SdFat Library
  2. * Copyright (C) 2012 by William Greiman
  3. *
  4. * This file is part of the Arduino SdFat Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Arduino SdFat Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef SdFat_h
  21. #define SdFat_h
  22. /**
  23. * \file
  24. * \brief SdFat class
  25. */
  26. #include "SdSpiCard.h"
  27. #include "SdFile.h"
  28. #include "utility/FatLib.h"
  29. //------------------------------------------------------------------------------
  30. /** SdFat version YYYYMMDD */
  31. #define SD_FAT_VERSION 20141115
  32. //==============================================================================
  33. /**
  34. * \class SdFatBase
  35. * \brief Virtual base class for %SdFat library.
  36. */
  37. class SdFatBase : public FatFileSystem {
  38. public:
  39. /** Initialize SD card and file system.
  40. * \param[in] spi SPI object for the card.
  41. * \param[in] csPin SD card chip select pin.
  42. * \param[in] divisor SPI divisor.
  43. * \return true for success else false.
  44. */
  45. bool begin(SdSpiCard::m_spi_t* spi, uint8_t csPin = SS, uint8_t divisor = 2) {
  46. return m_sdCard.begin(spi, csPin, divisor) &&
  47. FatFileSystem::begin(&m_vwd);
  48. }
  49. /** \return Pointer to SD card object */
  50. SdSpiCard *card() {return &m_sdCard;}
  51. /** %Print any SD error code to Serial and halt. */
  52. void errorHalt() {errorHalt(&Serial);}
  53. /** %Print any SD error code and halt.
  54. *
  55. * \param[in] pr Print destination.
  56. */
  57. void errorHalt(Print* pr);
  58. /** %Print msg, any SD error code and halt.
  59. *
  60. * \param[in] msg Message to print.
  61. */
  62. void errorHalt(char const* msg) {errorHalt(&Serial, msg);}
  63. /** %Print msg, any SD error code, and halt.
  64. *
  65. * \param[in] pr Print destination.
  66. * \param[in] msg Message to print.
  67. */
  68. void errorHalt(Print* pr, char const* msg);
  69. /** %Print msg, any SD error code, and halt.
  70. *
  71. * \param[in] msg Message to print.
  72. */
  73. void errorHalt(const __FlashStringHelper* msg) {errorHalt(&Serial, msg);}
  74. /** %Print msg, any SD error code, and halt.
  75. *
  76. * \param[in] pr Print destination.
  77. * \param[in] msg Message to print.
  78. */
  79. void errorHalt(Print* pr, const __FlashStringHelper* msg);
  80. /** %Print any SD error code to Serial */
  81. void errorPrint() {errorPrint(&Serial);}
  82. /** %Print any SD error code.
  83. * \param[in] pr Print device.
  84. */
  85. void errorPrint(Print* pr);
  86. /** %Print msg, any SD error code.
  87. *
  88. * \param[in] msg Message to print.
  89. */
  90. void errorPrint(const char* msg) {errorPrint(&Serial, msg);}
  91. /** %Print msg, any SD error code.
  92. *
  93. * \param[in] pr Print destination.
  94. * \param[in] msg Message to print.
  95. */
  96. void errorPrint(Print* pr, char const* msg);
  97. /** %Print msg, any SD error code.
  98. *
  99. * \param[in] msg Message to print.
  100. */
  101. void errorPrint(const __FlashStringHelper* msg) {errorPrint(&Serial, msg);}
  102. /** %Print msg, any SD error code.
  103. *
  104. * \param[in] pr Print destination.
  105. * \param[in] msg Message to print.
  106. */
  107. void errorPrint(Print* pr, const __FlashStringHelper* msg);
  108. /** Diagnostic call to initialize FatFileSystem.
  109. * \return true for success else false.
  110. */
  111. bool fsBegin() {return FatFileSystem::begin(&m_vwd);}
  112. /** %Print any SD error code and halt. */
  113. void initErrorHalt() {initErrorHalt(&Serial);}
  114. /** %Print error details and halt after begin fails.
  115. *
  116. * \param[in] pr Print destination.
  117. */
  118. void initErrorHalt(Print* pr);
  119. /**Print message, error details, and halt after SdFat::init() fails.
  120. *
  121. * \param[in] msg Message to print.
  122. */
  123. void initErrorHalt(char const *msg) {initErrorHalt(&Serial, msg);}
  124. /**Print message, error details, and halt after SdFatBase::init() fails.
  125. * \param[in] pr Print device.
  126. * \param[in] msg Message to print.
  127. */
  128. void initErrorHalt(Print* pr, char const *msg);
  129. /**Print message, error details, and halt after SdFat::init() fails.
  130. *
  131. * \param[in] msg Message to print.
  132. */
  133. void initErrorHalt(const __FlashStringHelper* msg) {
  134. initErrorHalt(&Serial, msg);
  135. }
  136. void initErrorHalt(Print* pr, const __FlashStringHelper* msg);
  137. /** Print error details after SdFat::init() fails. */
  138. void initErrorPrint() {initErrorPrint(&Serial);}
  139. /** Print error details after SdFatBase::init() fails.
  140. *
  141. * \param[in] pr Print destination.
  142. */
  143. void initErrorPrint(Print* pr);
  144. /**Print message and error details and halt after SdFat::init() fails.
  145. *
  146. * \param[in] msg Message to print.
  147. */
  148. void initErrorPrint(char const *msg) {initErrorPrint(&Serial, msg);}
  149. /**Print message and error details and halt after SdFatBase::init() fails.
  150. *
  151. * \param[in] pr Print destination.
  152. * \param[in] msg Message to print.
  153. */
  154. void initErrorPrint(Print* pr, char const *msg);
  155. /**Print message and error details and halt after SdFat::init() fails.
  156. *
  157. * \param[in] msg Message to print.
  158. */
  159. void initErrorPrint(const __FlashStringHelper* msg) {
  160. initErrorPrint(&Serial, msg);
  161. }
  162. /**Print message and error details and halt after SdFatBase::init() fails.
  163. *
  164. * \param[in] pr Print destination.
  165. * \param[in] msg Message to print.
  166. */
  167. void initErrorPrint(Print* pr, const __FlashStringHelper* msg);
  168. /** List the directory contents of the volume working directory to Serial.
  169. *
  170. * \param[in] flags The inclusive OR of
  171. *
  172. * LS_DATE - %Print file modification date
  173. *
  174. * LS_SIZE - %Print file size.
  175. *
  176. * LS_R - Recursive list of subdirectories.
  177. */
  178. void ls(uint8_t flags = 0) {
  179. ls(&Serial, flags);
  180. }
  181. /** List the directory contents of a directory to Serial.
  182. *
  183. * \param[in] path directory to list.
  184. *
  185. * \param[in] flags The inclusive OR of
  186. *
  187. * LS_DATE - %Print file modification date
  188. *
  189. * LS_SIZE - %Print file size.
  190. *
  191. * LS_R - Recursive list of subdirectories.
  192. */
  193. void ls(const char* path, uint8_t flags = 0) {
  194. ls(&Serial, path, flags);
  195. }
  196. /** open a file
  197. *
  198. * \param[in] path location of file to be opened.
  199. * \param[in] mode open mode flags.
  200. * \return a File object.
  201. */
  202. File open(const char *path, uint8_t mode = FILE_READ);
  203. /** \return a pointer to the volume working directory. */
  204. SdBaseFile* vwd() {return &m_vwd;}
  205. using FatFileSystem::ls;
  206. private:
  207. uint8_t cardErrorCode() {return m_sdCard.errorCode();}
  208. uint8_t cardErrorData() {return m_sdCard.errorData();}
  209. bool readBlock(uint32_t block, uint8_t* dst) {
  210. return m_sdCard.readBlock(block, dst);
  211. }
  212. bool writeBlock(uint32_t block, const uint8_t* src) {
  213. return m_sdCard.writeBlock(block, src);
  214. }
  215. bool readBlocks(uint32_t block, uint8_t* dst, size_t n) {
  216. return m_sdCard.readBlocks(block, dst, n);
  217. }
  218. bool writeBlocks(uint32_t block, const uint8_t* src, size_t n) {
  219. return m_sdCard.writeBlocks(block, src, n);
  220. }
  221. SdBaseFile m_vwd;
  222. SdSpiCard m_sdCard;
  223. };
  224. //==============================================================================
  225. /**
  226. * \class SdFat
  227. * \brief Main file system class for %SdFat library.
  228. */
  229. class SdFat : public SdFatBase {
  230. public:
  231. /** Initialize SD card and file system.
  232. *
  233. * \param[in] csPin SD card chip select pin.
  234. * \param[in] divisor SPI divisor.
  235. * \return true for success else false.
  236. */
  237. bool begin(uint8_t csPin = SS, uint8_t divisor = 2) {
  238. return SdFatBase::begin(&m_spi, csPin, divisor);
  239. }
  240. /** Initialize SD card - use for diagnostic purposes.
  241. * \param[in] csPin SD card chip select pin.
  242. * \param[in] divisor SPI divisor.
  243. * \return true for success else false.
  244. */
  245. bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) {
  246. return card()->begin(&m_spi, csPin, divisor);
  247. }
  248. private:
  249. SpiDefault_t m_spi;
  250. };
  251. //==============================================================================
  252. #if USE_MULTIPLE_SPI_TYPES || defined(DOXYGEN)
  253. /**
  254. * \class SdFatLibSpi
  255. * \brief SdFat class using the standard Arduino SPI library.
  256. */
  257. class SdFatLibSpi: public SdFatBase {
  258. public:
  259. /** Initialize SD card and file system.
  260. *
  261. * \param[in] csPin SD card chip select pin.
  262. * \param[in] divisor SPI divisor.
  263. * \return true for success else false.
  264. */
  265. bool begin(uint8_t csPin = SS, uint8_t divisor = 2) {
  266. return SdFatBase::begin(&m_spi, csPin, divisor);
  267. }
  268. /** Initialize SD card - use for diagnostic purposes.
  269. * \param[in] csPin SD card chip select pin.
  270. * \param[in] divisor SPI divisor.
  271. * \return true for success else false.
  272. */
  273. bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) {
  274. return card()->begin(&m_spi, csPin, divisor);
  275. }
  276. private:
  277. SdSpiLib m_spi;
  278. };
  279. //==============================================================================
  280. /**
  281. * \class SdFatSoftSpi
  282. * \brief SdFat class using software SPI.
  283. */
  284. template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
  285. class SdFatSoftSpi : public SdFatBase {
  286. public:
  287. /** Initialize SD card and file system.
  288. *
  289. * \param[in] csPin SD card chip select pin.
  290. * \param[in] divisor SPI divisor.
  291. * \return true for success else false.
  292. */
  293. bool begin(uint8_t csPin = SS, uint8_t divisor = 2) {
  294. return SdFatBase::begin(&m_spi, csPin, divisor);
  295. }
  296. /** Initialize SD card - use for diagnostic purposes.
  297. * \param[in] csPin SD card chip select pin.
  298. * \param[in] divisor SPI divisor.
  299. * \return true for success else false.
  300. */
  301. bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) {
  302. return card()->begin(&m_spi, csPin, divisor);
  303. }
  304. private:
  305. SdSpiSoft<MisoPin, MosiPin, SckPin> m_spi;
  306. };
  307. #endif // USE_MULTIPLE_SPI_TYPES
  308. #endif // SdFat_h