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.

SdSpiCard.h 9.7KB

10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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 <Arduino.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_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. /** Erase a range of blocks.
  61. *
  62. * \param[in] firstBlock The address of the first block in the range.
  63. * \param[in] lastBlock The address of the last block in the range.
  64. *
  65. * \note This function requests the SD card to do a flash erase for a
  66. * range of blocks. The data on the card after an erase operation is
  67. * either 0 or 1, depends on the card vendor. The card must support
  68. * single block erase.
  69. *
  70. * \return The value true is returned for success and
  71. * the value false is returned for failure.
  72. */
  73. bool erase(uint32_t firstBlock, uint32_t lastBlock);
  74. /** Determine if card supports single block erase.
  75. *
  76. * \return true is returned if single block erase is supported.
  77. * false is returned if single block erase is not supported.
  78. */
  79. bool eraseSingleBlockEnable();
  80. /**
  81. * Set SD error code.
  82. * \param[in] code value for error code.
  83. */
  84. void error(uint8_t code) {
  85. m_errorCode = code;
  86. }
  87. /**
  88. * \return code for the last error. See SdSpiCard.h for a list of error codes.
  89. */
  90. int errorCode() const {
  91. return m_errorCode;
  92. }
  93. /** \return error data for last error. */
  94. int errorData() const {
  95. return m_status;
  96. }
  97. /**
  98. * Check for busy. MISO low indicates the card is busy.
  99. *
  100. * \return true if busy else false.
  101. */
  102. bool isBusy();
  103. /**
  104. * Read a 512 byte block from an SD card.
  105. *
  106. * \param[in] block Logical block to be read.
  107. * \param[out] dst Pointer to the location that will receive the data.
  108. * \return The value true is returned for success and
  109. * the value false is returned for failure.
  110. */
  111. bool readBlock(uint32_t block, uint8_t* dst);
  112. /**
  113. * Read multiple 512 byte blocks from an SD card.
  114. *
  115. * \param[in] block Logical block to be read.
  116. * \param[in] count Number of blocks 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 readBlocks(uint32_t block, uint8_t* dst, size_t count);
  122. /**
  123. * Read a card's CID register. The CID contains card identification
  124. * information such as Manufacturer ID, Product name, Product serial
  125. * number and Manufacturing date.
  126. *
  127. * \param[out] cid pointer to area for returned data.
  128. *
  129. * \return true for success or false for failure.
  130. */
  131. bool readCID(cid_t* cid) {
  132. return readRegister(CMD10, cid);
  133. }
  134. /**
  135. * Read a card's CSD register. The CSD contains Card-Specific Data that
  136. * provides information regarding access to the card's contents.
  137. *
  138. * \param[out] csd pointer to area for returned data.
  139. *
  140. * \return true for success or false for failure.
  141. */
  142. bool readCSD(csd_t* csd) {
  143. return readRegister(CMD9, csd);
  144. }
  145. /** Read one data block in a multiple block read sequence
  146. *
  147. * \param[out] dst Pointer to the location for the data to be read.
  148. *
  149. * \return The value true is returned for success and
  150. * the value false is returned for failure.
  151. */
  152. bool readData(uint8_t *dst);
  153. /** Read OCR register.
  154. *
  155. * \param[out] ocr Value of OCR register.
  156. * \return true for success else false.
  157. */
  158. bool readOCR(uint32_t* ocr);
  159. /** Start a read multiple blocks sequence.
  160. *
  161. * \param[in] blockNumber Address of first block in sequence.
  162. *
  163. * \note This function is used with readData() and readStop() for optimized
  164. * multiple block reads. SPI chipSelect must be low for the entire sequence.
  165. *
  166. * \return The value true is returned for success and
  167. * the value false is returned for failure.
  168. */
  169. bool readStart(uint32_t blockNumber);
  170. /** End a read multiple blocks sequence.
  171. *
  172. * \return The value true is returned for success and
  173. * the value false is returned for failure.
  174. */
  175. bool readStop();
  176. /** Return SCK divisor.
  177. *
  178. * \return Requested SCK divisor.
  179. */
  180. uint8_t sckDivisor() {
  181. return m_sckDivisor;
  182. }
  183. /** Return the card type: SD V1, SD V2 or SDHC
  184. * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
  185. */
  186. int type() const {
  187. return m_type;
  188. }
  189. /**
  190. * Writes a 512 byte block to an SD card.
  191. *
  192. * \param[in] blockNumber Logical block to be written.
  193. * \param[in] src Pointer to the location of the data to be written.
  194. * \return The value true is returned for success and
  195. * the value false is returned for failure.
  196. */
  197. bool writeBlock(uint32_t blockNumber, const uint8_t* src);
  198. /**
  199. * Write multiple 512 byte blocks to an SD card.
  200. *
  201. * \param[in] block Logical block to be written.
  202. * \param[in] count Number of blocks to be written.
  203. * \param[in] src Pointer to the location of the data to be written.
  204. * \return The value true is returned for success and
  205. * the value false is returned for failure.
  206. */
  207. bool writeBlocks(uint32_t block, const uint8_t* src, size_t count);
  208. /** Write one data block in a multiple block write sequence
  209. * \param[in] src Pointer to the location of the data to be written.
  210. * \return The value true is returned for success and
  211. * the value false is returned for failure.
  212. */
  213. bool writeData(const uint8_t* src);
  214. /** Start a write multiple blocks sequence.
  215. *
  216. * \param[in] blockNumber Address of first block in sequence.
  217. * \param[in] eraseCount The number of blocks to be pre-erased.
  218. *
  219. * \note This function is used with writeData() and writeStop()
  220. * for optimized multiple block writes.
  221. *
  222. * \return The value true is returned for success and
  223. * the value false is returned for failure.
  224. */
  225. bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
  226. /** End a write multiple blocks sequence.
  227. *
  228. * \return The value true is returned for success and
  229. * the value false is returned for failure.
  230. */
  231. bool writeStop();
  232. private:
  233. // private functions
  234. uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
  235. cardCommand(CMD55, 0);
  236. return cardCommand(cmd, arg);
  237. }
  238. uint8_t cardCommand(uint8_t cmd, uint32_t arg);
  239. bool readData(uint8_t* dst, size_t count);
  240. bool readRegister(uint8_t cmd, void* buf);
  241. void chipSelectHigh();
  242. void chipSelectLow();
  243. void spiYield();
  244. void type(uint8_t value) {
  245. m_type = value;
  246. }
  247. bool waitNotBusy(uint16_t timeoutMillis);
  248. bool writeData(uint8_t token, const uint8_t* src);
  249. void spiBegin() {
  250. m_spi->begin();
  251. }
  252. void spiInit(uint8_t spiDivisor) {
  253. m_spi->init(spiDivisor);
  254. }
  255. uint8_t spiReceive() {
  256. return m_spi->receive();
  257. }
  258. uint8_t spiReceive(uint8_t* buf, size_t n) {
  259. return m_spi->receive(buf, n);
  260. }
  261. void spiSend(uint8_t data) {
  262. m_spi->send(data);
  263. }
  264. void spiSend(const uint8_t* buf, size_t n) {
  265. m_spi->send(buf, n);
  266. }
  267. bool useSpiTransactions() {
  268. return m_spi->useSpiTransactions();
  269. }
  270. m_spi_t* m_spi;
  271. uint8_t m_chipSelectPin;
  272. uint8_t m_errorCode;
  273. uint8_t m_sckDivisor;
  274. uint8_t m_status;
  275. uint8_t m_type;
  276. };
  277. //==============================================================================
  278. /**
  279. * \class Sd2Card
  280. * \brief Raw access to SD and SDHC card using default SPI library.
  281. */
  282. class Sd2Card : public SdSpiCard {
  283. public:
  284. /** Initialize the SD card.
  285. * \param[in] chipSelectPin SD chip select pin.
  286. * \param[in] sckDivisor SPI clock divisor.
  287. * \return true for success else false.
  288. */
  289. bool begin(uint8_t chipSelectPin = SS, uint8_t sckDivisor = 2) {
  290. return SdSpiCard::begin(&m_spi, chipSelectPin, sckDivisor);
  291. }
  292. /** Initialize the SD card. Obsolete form.
  293. * \param[in] chipSelectPin SD chip select pin.
  294. * \param[in] sckDivisor SPI clock divisor.
  295. * \return true for success else false.
  296. */
  297. bool init(uint8_t sckDivisor = 2, uint8_t chipSelectPin = SS) {
  298. return begin(chipSelectPin, sckDivisor);
  299. }
  300. private:
  301. bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS,
  302. uint8_t sckDivisor = SPI_FULL_SPEED) {
  303. return false;
  304. }
  305. SpiDefault_t m_spi;
  306. };
  307. #endif // SpiCard_h