Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

319 lines
10KB

  1. /* Arduino SdSpiCard Library
  2. * Copyright (C) 2012 by William Greiman
  3. *
  4. * This file is part of the Arduino SdSpiCard 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 SdSpiCard Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef SpiCard_h
  21. #define SpiCard_h
  22. /**
  23. * \file
  24. * \brief SdSpiCard class for V2 SD/SDHC cards
  25. */
  26. #include "SystemInclude.h"
  27. #include "SdFatConfig.h"
  28. #include "SdInfo.h"
  29. #include "SdSpi.h"
  30. //==============================================================================
  31. /**
  32. * \class SdSpiCard
  33. * \brief Raw access to SD and SDHC flash memory cards via SPI protocol.
  34. */
  35. class SdSpiCard {
  36. public:
  37. /** typedef for SPI class. */
  38. #if SD_SPI_CONFIGURATION < 3
  39. typedef SpiDefault_t m_spi_t;
  40. #else // SD_SPI_CONFIGURATION < 3
  41. typedef SdSpiBase m_spi_t;
  42. #endif // SD_SPI_CONFIGURATION < 3
  43. /** Construct an instance of SdSpiCard. */
  44. SdSpiCard() : m_selected(false), m_errorCode(SD_CARD_ERROR_INIT_NOT_CALLED), m_type(0) {}
  45. /** Initialize the SD card.
  46. * \param[in] spi SPI object.
  47. * \param[in] chipSelectPin SD chip select pin.
  48. * \param[in] sckDivisor SPI clock divisor.
  49. * \return true for success else false.
  50. */
  51. bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS,
  52. uint8_t sckDivisor = SPI_FULL_SPEED);
  53. /**
  54. * Determine the size of an SD flash memory card.
  55. *
  56. * \return The number of 512 byte data blocks in the card
  57. * or zero if an error occurs.
  58. */
  59. uint32_t cardSize();
  60. /** Set the SD chip select pin high, send a dummy byte, and call SPI endTransaction.
  61. *
  62. * This function should only be called by programs doing raw I/O to the SD.
  63. */
  64. void chipSelectHigh();
  65. /** Set the SD chip select pin low and call SPI beginTransaction.
  66. *
  67. * This function should only be called by programs doing raw I/O to the SD.
  68. */
  69. void chipSelectLow();
  70. /** Erase a range of blocks.
  71. *
  72. * \param[in] firstBlock The address of the first block in the range.
  73. * \param[in] lastBlock The address of the last block in the range.
  74. *
  75. * \note This function requests the SD card to do a flash erase for a
  76. * range of blocks. The data on the card after an erase operation is
  77. * either 0 or 1, depends on the card vendor. The card must support
  78. * single block erase.
  79. *
  80. * \return The value true is returned for success and
  81. * the value false is returned for failure.
  82. */
  83. bool erase(uint32_t firstBlock, uint32_t lastBlock);
  84. /** Determine if card supports single block erase.
  85. *
  86. * \return true is returned if single block erase is supported.
  87. * false is returned if single block erase is not supported.
  88. */
  89. bool eraseSingleBlockEnable();
  90. /**
  91. * Set SD error code.
  92. * \param[in] code value for error code.
  93. */
  94. void error(uint8_t code) {
  95. m_errorCode = code;
  96. }
  97. /**
  98. * \return code for the last error. See SdSpiCard.h for a list of error codes.
  99. */
  100. int errorCode() const {
  101. return m_errorCode;
  102. }
  103. /** \return error data for last error. */
  104. int errorData() const {
  105. return m_status;
  106. }
  107. /**
  108. * Check for busy. MISO low indicates the card is busy.
  109. *
  110. * \return true if busy else false.
  111. */
  112. bool isBusy();
  113. /**
  114. * Read a 512 byte block from an SD card.
  115. *
  116. * \param[in] block Logical block to be read.
  117. * \param[out] dst Pointer to the location that will receive the data.
  118. * \return The value true is returned for success and
  119. * the value false is returned for failure.
  120. */
  121. bool readBlock(uint32_t block, uint8_t* dst);
  122. /**
  123. * Read multiple 512 byte blocks from an SD card.
  124. *
  125. * \param[in] block Logical block to be read.
  126. * \param[in] count Number of blocks to be read.
  127. * \param[out] dst Pointer to the location that will receive the data.
  128. * \return The value true is returned for success and
  129. * the value false is returned for failure.
  130. */
  131. bool readBlocks(uint32_t block, uint8_t* dst, size_t count);
  132. /**
  133. * Read a card's CID register. The CID contains card identification
  134. * information such as Manufacturer ID, Product name, Product serial
  135. * number and Manufacturing date.
  136. *
  137. * \param[out] cid pointer to area for returned data.
  138. *
  139. * \return true for success or false for failure.
  140. */
  141. bool readCID(cid_t* cid) {
  142. return readRegister(CMD10, cid);
  143. }
  144. /**
  145. * Read a card's CSD register. The CSD contains Card-Specific Data that
  146. * provides information regarding access to the card's contents.
  147. *
  148. * \param[out] csd pointer to area for returned data.
  149. *
  150. * \return true for success or false for failure.
  151. */
  152. bool readCSD(csd_t* csd) {
  153. return readRegister(CMD9, csd);
  154. }
  155. /** Read one data block in a multiple block read sequence
  156. *
  157. * \param[out] dst Pointer to the location for the data to be read.
  158. *
  159. * \return The value true is returned for success and
  160. * the value false is returned for failure.
  161. */
  162. bool readData(uint8_t *dst);
  163. /** Read OCR register.
  164. *
  165. * \param[out] ocr Value of OCR register.
  166. * \return true for success else false.
  167. */
  168. bool readOCR(uint32_t* ocr);
  169. /** Start a read multiple blocks sequence.
  170. *
  171. * \param[in] blockNumber Address of first block in sequence.
  172. *
  173. * \note This function is used with readData() and readStop() for optimized
  174. * multiple block reads. SPI chipSelect must be low for the entire sequence.
  175. *
  176. * \return The value true is returned for success and
  177. * the value false is returned for failure.
  178. */
  179. bool readStart(uint32_t blockNumber);
  180. /** End a read multiple blocks sequence.
  181. *
  182. * \return The value true is returned for success and
  183. * the value false is returned for failure.
  184. */
  185. bool readStop();
  186. /** Return SCK divisor.
  187. *
  188. * \return Requested SCK divisor.
  189. */
  190. uint8_t sckDivisor() {
  191. return m_sckDivisor;
  192. }
  193. /** \return the SD chip select status, true if slected else false. */
  194. bool selected() {return m_selected;}
  195. /** Return the card type: SD V1, SD V2 or SDHC
  196. * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
  197. */
  198. int type() const {
  199. return m_type;
  200. }
  201. /**
  202. * Writes a 512 byte block to an SD card.
  203. *
  204. * \param[in] blockNumber Logical block to be written.
  205. * \param[in] src Pointer to the location of the data to be written.
  206. * \return The value true is returned for success and
  207. * the value false is returned for failure.
  208. */
  209. bool writeBlock(uint32_t blockNumber, const uint8_t* src);
  210. /**
  211. * Write multiple 512 byte blocks to an SD card.
  212. *
  213. * \param[in] block Logical block to be written.
  214. * \param[in] count Number of blocks to be written.
  215. * \param[in] src Pointer to the location of the data to be written.
  216. * \return The value true is returned for success and
  217. * the value false is returned for failure.
  218. */
  219. bool writeBlocks(uint32_t block, const uint8_t* src, size_t count);
  220. /** Write one data block in a multiple block write sequence
  221. * \param[in] src Pointer to the location of the data to be written.
  222. * \return The value true is returned for success and
  223. * the value false is returned for failure.
  224. */
  225. bool writeData(const uint8_t* src);
  226. /** Start a write multiple blocks sequence.
  227. *
  228. * \param[in] blockNumber Address of first block in sequence.
  229. * \param[in] eraseCount The number of blocks to be pre-erased.
  230. *
  231. * \note This function is used with writeData() and writeStop()
  232. * for optimized multiple block writes.
  233. *
  234. * \return The value true is returned for success and
  235. * the value false is returned for failure.
  236. */
  237. bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
  238. /** End a write multiple blocks sequence.
  239. *
  240. * \return The value true is returned for success and
  241. * the value false is returned for failure.
  242. */
  243. bool writeStop();
  244. private:
  245. // private functions
  246. uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
  247. cardCommand(CMD55, 0);
  248. return cardCommand(cmd, arg);
  249. }
  250. uint8_t cardCommand(uint8_t cmd, uint32_t arg);
  251. bool readData(uint8_t* dst, size_t count);
  252. bool readRegister(uint8_t cmd, void* buf);
  253. void type(uint8_t value) {
  254. m_type = value;
  255. }
  256. bool waitNotBusy(uint16_t timeoutMillis);
  257. bool writeData(uint8_t token, const uint8_t* src);
  258. void spiBegin(uint8_t chipSelectPin) {
  259. m_spi->begin(chipSelectPin);
  260. }
  261. void spiBeginTransaction(uint8_t spiDivisor) {
  262. m_spi->beginTransaction(spiDivisor);
  263. }
  264. void spiEndTransaction() {
  265. m_spi->endTransaction();
  266. }
  267. uint8_t spiReceive() {
  268. return m_spi->receive();
  269. }
  270. uint8_t spiReceive(uint8_t* buf, size_t n) {
  271. return m_spi->receive(buf, n);
  272. }
  273. void spiSend(uint8_t data) {
  274. m_spi->send(data);
  275. }
  276. void spiSend(const uint8_t* buf, size_t n) {
  277. m_spi->send(buf, n);
  278. }
  279. m_spi_t* m_spi;
  280. bool m_selected;
  281. uint8_t m_chipSelectPin;
  282. uint8_t m_errorCode;
  283. uint8_t m_sckDivisor;
  284. uint8_t m_status;
  285. uint8_t m_type;
  286. };
  287. //==============================================================================
  288. /**
  289. * \class Sd2Card
  290. * \brief Raw access to SD and SDHC card using default SPI library.
  291. */
  292. class Sd2Card : public SdSpiCard {
  293. public:
  294. /** Initialize the SD card.
  295. * \param[in] chipSelectPin SD chip select pin.
  296. * \param[in] sckDivisor SPI clock divisor.
  297. * \return true for success else false.
  298. */
  299. bool begin(uint8_t chipSelectPin = SS, uint8_t sckDivisor = 2) {
  300. return SdSpiCard::begin(&m_spi, chipSelectPin, sckDivisor);
  301. }
  302. /** Initialize the SD card. Obsolete form.
  303. * \param[in] chipSelectPin SD chip select pin.
  304. * \param[in] sckDivisor SPI clock divisor.
  305. * \return true for success else false.
  306. */
  307. bool init(uint8_t sckDivisor = 2, uint8_t chipSelectPin = SS) {
  308. return begin(chipSelectPin, sckDivisor);
  309. }
  310. private:
  311. bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS,
  312. uint8_t sckDivisor = SPI_FULL_SPEED) {
  313. return false;
  314. }
  315. SpiDefault_t m_spi;
  316. };
  317. #endif // SpiCard_h