app_sdcard.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /**
  2. * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "sdk_config.h"
  41. #if APP_SDCARD_ENABLED
  42. #include "app_sdcard.h"
  43. #include "nrf_gpio.h"
  44. #include "nrf_drv_spi.h"
  45. #include "app_error.h"
  46. #include "nrf_assert.h"
  47. #include "nrf_pt.h"
  48. #define CMD_MASK 0x40
  49. #define ACMD_MASK 0x80
  50. #define CMD0 (CMD_MASK | 0) /**< SDC/MMC command 0: GO_IDLE_STATE. */
  51. #define CMD1 (CMD_MASK | 1) /**< SDC/MMC command 1: SEND_OP_COND (MMC). */
  52. #define CMD8 (CMD_MASK | 8) /**< SDC/MMC command 8: SEND_IF_COND. */
  53. #define CMD9 (CMD_MASK | 9) /**< SDC/MMC command 9: SEND_CSD. */
  54. #define CMD10 (CMD_MASK | 10) /**< SDC/MMC command 10: SEND_CID. */
  55. #define CMD12 (CMD_MASK | 12) /**< SDC/MMC command 12: STOP_TRANSMISSION. */
  56. #define CMD16 (CMD_MASK | 16) /**< SDC/MMC command 16: SET_BLOCKLEN. */
  57. #define CMD17 (CMD_MASK | 17) /**< SDC/MMC command 17: READ_SINGLE_BLOCK. */
  58. #define CMD18 (CMD_MASK | 18) /**< SDC/MMC command 18: READ_MULTIPLE_BLOCK. */
  59. #define CMD23 (CMD_MASK | 23) /**< SDC/MMC command 23: SET_BLOCK_COUNT (MMC). */
  60. #define CMD24 (CMD_MASK | 24) /**< SDC/MMC command 24: WRITE_BLOCK. */
  61. #define CMD25 (CMD_MASK | 25) /**< SDC/MMC command 25: WRITE_MULTIPLE_BLOCK. */
  62. #define CMD32 (CMD_MASK | 32) /**< SDC/MMC command 32: ERASE_ER_BLK_START. */
  63. #define CMD33 (CMD_MASK | 33) /**< SDC/MMC command 33: ERASE_ER_BLK_END. */
  64. #define CMD38 (CMD_MASK | 38) /**< SDC/MMC command 38: ERASE. */
  65. #define CMD55 (CMD_MASK | 55) /**< SDC/MMC command 55: APP_CMD. */
  66. #define CMD58 (CMD_MASK | 58) /**< SDC/MMC command 58: READ_OCR. */
  67. #define ACMD13 (ACMD_MASK | CMD_MASK | 13) /**< SDC application command 13: SD_STATUS. */
  68. #define ACMD23 (ACMD_MASK | CMD_MASK | 23) /**< SDC application command 23: SET_WR_BLK_ERASE_COUNT. */
  69. #define ACMD41 (ACMD_MASK | CMD_MASK | 41) /**< SDC application command 41: SEND_OP_COND. */
  70. #define IS_ACMD(CMD) ((CMD) & ACMD_MASK) /**< Check if command is an application command (ACMD). */
  71. #define SDC_COMMAND_LEN 6 /**< Length of a command structure sent to the card. */
  72. #define SDC_COMMAND_POS 0 /**< Position of a command field inside the command structure. */
  73. #define SDC_COMMAND_MASK 0x7F /**< Bit mask of a command field. */
  74. #define SDC_COMMAND_ARG_POS 1 /**< Position of a 32-bit argument inside the command structure. */
  75. #define SDC_COMMAND_CRC_POS 5 /**< Position of a CRC field inside the command structure. */
  76. #define SDC_MAX_NCR 8 /**< Maximum number of "busy" bytes sent before command response. */
  77. #define SDC_R1_LEN 1 /**< Length of R1 format response. */
  78. #define SDC_R3_LEN 5 /**< Length of R3 format response. */
  79. #define SDC_R7_LEN 5 /**< Length of R7 format response. */
  80. #define SDC_R_MAX_LEN 5 /**< Maximum length of command response. */
  81. #define SDC_FLAG_IN_IDLE_STATE 0x01 /**< R1 response flag bit mask: idle state. */
  82. #define SDC_FLAG_ERASE_RESET 0x02 /**< R1 response flag bit mask: erase reset. */
  83. #define SDC_FLAG_ILLEGAL_COMMAND 0x04 /**< R1 response flag bit mask: illegal command. */
  84. #define SDC_FLAG_COM_CRC_ERROR 0x08 /**< R1 response flag bit mask: CRC error. */
  85. #define SDC_FLAG_ERASE_SEQUENCE_ERROR 0x10 /**< R1 response flag bit mask: erase sequence error. */
  86. #define SDC_FLAG_ADDRESS_ERROR 0x20 /**< R1 response flag bit mask: address error. */
  87. #define SDC_FLAG_PARAMETER_ERROR 0x40 /**< R1 response flag bit mask: parameter error. */
  88. #define SDC_HCS_FLAG_MASK (1uL << 30) /**< High capacity support bit mask. */
  89. #define SDC_EMPTY_BYTE 0xFF /**< Idle state token. */
  90. #define SDC_BUSY_BYTE 0x00 /**< Busy byte token. */
  91. #define SDC_TOKEN_START_BLOCK 0xFE /**< Data block start token. */
  92. #define SDC_TOKEN_START_BLOCK_MULT 0xFC /**< Data block start token for multiple write operation. */
  93. #define SDC_TOKEN_DATA_RESP_MASK 0x1F /**< Data response token mask. */
  94. #define SDC_TOKEN_DATA_RESP_ACCEPTED 0x05 /**< Data response message: accepted. */
  95. #define SDC_TOKEN_DATA_RESP_CRC_ERR 0x0B /**< Data response message: CRC error. */
  96. #define SDC_TOKEN_DATA_RESP_DATA_ERR 0x0D /**< Data response message: data error. */
  97. #define SDC_TOKEN_STOP_TRAN 0xFD /**< Stop transmission token. */
  98. #define SDC_MAX_RETRY_COUNT_INIT 2000 /**< Maximum number of retries while card is busy (identification stage). */
  99. #define SDC_MAX_RETRY_COUNT 20000 /**< Maximum number of retries while card is busy. */
  100. #define SDC_SPI_MTU 240 /**< Maximum number of bytes in one SPI transaction. */
  101. #define SDC_CRC_CMD0 0x95 /**< Fixed CRC for reset command. */
  102. #define SDC_CRC_CMD8 0x87 /**< Fixed CRC for CMD8. */
  103. #define SDC_CRC_DUMMY 0xFF /**< Dummy CRC value. */
  104. #define SDC_CMD_BUF_LEN 16 /**< Size of a buffer for storing SDC commands. */
  105. #define SDC_WORK_BUF_LEN 16 /**< Size of a working buffer. */
  106. #define SDC_DATA_WAIT_TX_SIZE 16 /**< Number of bytes sent during data / busy wait. */
  107. #define SDC_CS_ASSERT() do { nrf_gpio_pin_clear(m_cb.cs_pin); } while (0) /**< Set CS pin to active state. */
  108. #define SDC_CS_DEASSERT() do { nrf_gpio_pin_set(m_cb.cs_pin); } while (0) /**< Set CS pin to inactive state. */
  109. #define SDC_PT &m_cb.state.pt /**< Macro for getting SDC task structure pointer (Protothread). */
  110. #define SDC_PT_SUB &m_cb.state.pt_sub /**< Macro for getting SDC sub-task structure pointer (Protothread). */
  111. /** Break current task (Protothread). */
  112. #define SDC_BREAK(PT, EXIT_CODE) do { \
  113. *p_exit_code = (EXIT_CODE); \
  114. PT_EXIT(PT); \
  115. } while (0)
  116. /**< Check the value of R1 response and break current task on error. */
  117. #define SDC_RESP_CHECK(PT, R1) do { \
  118. if ((R1) & ~(SDC_FLAG_IN_IDLE_STATE | SDC_FLAG_ERASE_RESET)) \
  119. { \
  120. SDC_BREAK((PT), SDC_ERROR_COMMUNICATION); \
  121. } \
  122. } while (0)
  123. /**< Check the result of an SDC operation and break on failure. */
  124. #define SDC_RESULT_CHECK(PT, RESULT) do { \
  125. if ((RESULT) != SDC_SUCCESS) \
  126. { \
  127. SDC_BREAK((PT), RESULT); \
  128. } \
  129. } while (0);
  130. static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(APP_SDCARD_SPI_INSTANCE); /**< SPI instance. */
  131. /**
  132. * @brief SDC response type.
  133. */
  134. typedef enum {
  135. SDC_RNONE = 0,
  136. SDC_R1,
  137. SDC_R3,
  138. SDC_R7
  139. } sdc_response_t;
  140. /**
  141. * @brief SDC operation state.
  142. */
  143. typedef enum {
  144. SDC_UNINITIALIZED = 0, ///< Card not initialized.
  145. SDC_OP_RESET = 1, ///< Reset state.
  146. SDC_OP_IDENTIFICATION = 2, ///< Identification procedure.
  147. SDC_OP_IDLE = 3, ///< Idle state.
  148. SDC_OP_READ = 4, ///< Data read procedure.
  149. SDC_OP_WRITE = 5 ///< Data write procedure.
  150. } sdc_op_t;
  151. /**
  152. * @brief SDC data bus state.
  153. */
  154. typedef enum {
  155. SDC_BUS_IDLE = 0, ///< Idle state, no active transfer.
  156. SDC_BUS_CMD = 1, ///< Command is being transfered.
  157. SDC_BUS_ACMD = 2, ///< Application command header transfer.
  158. SDC_BUS_DATA_WAIT = 3, ///< Data wait state.
  159. SDC_BUS_DATA = 4 ///< Data block transfer in progress.
  160. } sdc_bus_state_t;
  161. /**
  162. * @brief Current read/write operation state structure.
  163. */
  164. typedef struct {
  165. uint8_t * buffer; ///< Local data buffer.
  166. uint32_t address; ///< Data block address.
  167. uint16_t block_count; ///< Total number of blocks in read/write operation.
  168. uint16_t blocks_left; ///< Blocks left in current read/write operation.
  169. uint16_t position; ///< Number of blocks left to read/write.
  170. } sdc_rw_op_t;
  171. /**
  172. * @brief SDC state structure.
  173. */
  174. typedef struct {
  175. sdc_rw_op_t rw_op; ///< Read/write operation state.
  176. pt_t pt; ///< Current task (Protothread) state.
  177. pt_t pt_sub; ///< Current sub-task (Protothread) state.
  178. uint16_t retry_count; ///< Number of retries left.
  179. volatile sdc_op_t op; ///< Current operation.
  180. sdc_bus_state_t bus_state; ///< Current data bud state.
  181. uint8_t rsp_len; ///< Expected response length.
  182. } sdc_state_t;
  183. /**
  184. * @beirf SDC control block.
  185. */
  186. typedef struct {
  187. sdc_event_handler_t handler; ///< Event handler.
  188. app_sdc_info_t info; ///< Card information structure.
  189. sdc_state_t state; ///< Card state structure
  190. uint8_t cmd_buf[SDC_CMD_BUF_LEN]; ///< Command buffer.
  191. uint8_t rsp_buf[SDC_CMD_BUF_LEN]; ///< Card response buffer.
  192. uint8_t work_buf[SDC_WORK_BUF_LEN]; ///< Working buffer
  193. uint8_t cs_pin; ///< Chip select pin number.
  194. } sdc_cb_t;
  195. static sdc_cb_t m_cb; ///< SDC control block.
  196. /**
  197. * @brief Function for requesting the SPI transaction.
  198. *
  199. * The SPI bus must be initialized prior to use of this function.
  200. *
  201. * @param[in] p_txb Pointer to the TX buffer.
  202. * @param[in] tx_len TX buffer length.
  203. * @param[out] p_rxb Pointer to the RX buffer.
  204. * @param[in] tx_len RX buffer length.
  205. */
  206. __STATIC_INLINE void sdc_spi_transfer(uint8_t const * const p_txb,
  207. uint8_t tx_len,
  208. uint8_t * const p_rxb,
  209. uint8_t rx_len)
  210. {
  211. SDC_CS_ASSERT();
  212. ret_code_t err_code = nrf_drv_spi_transfer(&m_spi, p_txb, tx_len, p_rxb, rx_len);
  213. APP_ERROR_CHECK(err_code);
  214. }
  215. /**
  216. * @brief Function for switching the SPI clock to high speed mode.
  217. */
  218. __STATIC_INLINE void sdc_spi_hispeed(void)
  219. {
  220. #ifdef SPI_PRESENT
  221. nrf_spi_frequency_set(m_spi.u.spi.p_reg,
  222. (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
  223. #else
  224. nrf_spim_frequency_set(m_spi.u.spim.p_reg,
  225. (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
  226. #endif
  227. }
  228. /**
  229. * @brief Function for extracting the number of data block from the CSD structure.
  230. *
  231. * @param[in] p_csd Pointer to the card CSD structure.
  232. *
  233. * @return Number of data blocks or 0 if unsupported / invalid structure was provided.
  234. */
  235. static uint32_t sdc_calculate_size(uint8_t const * const p_csd)
  236. {
  237. // Values are calculated as stated in SD Specifications, chapter 5.3.
  238. uint8_t csd_version = p_csd[0] >> 6;
  239. switch (csd_version)
  240. {
  241. case 0:
  242. case 2:
  243. {
  244. // SD Standard Capacity or MMC.
  245. uint32_t c_size = ((uint32_t) p_csd[8] >> 6) + (((uint32_t) p_csd[7]) << 2)
  246. + ((uint32_t)(p_csd[6] & 0x03) << 10);
  247. uint32_t read_bl_len = p_csd[5] & 0x0F;
  248. uint32_t c_size_mult = ((p_csd[10] & 0x80) >> 7) + ((p_csd[9] & 0x03) << 1);
  249. // Block size in this implementation is set to 512, so the resulting number of bytes
  250. // is divided by 512 (2^9)
  251. return (c_size + 1) << (read_bl_len + c_size_mult + 2 - 9);
  252. }
  253. case 1:
  254. {
  255. // SD High Capacity.
  256. uint32_t c_size = (uint32_t) p_csd[9] + ((uint32_t) p_csd[8] << 8)
  257. + (((uint32_t) p_csd[7] & 0x3F) << 16);
  258. // According to SD 2.0 Specifications, capacity = (C_SIZE + 1) * 512KByte.
  259. // Block size is equal to 512, so the result is divided by 512.
  260. return (c_size + 1) * 1024uL;
  261. }
  262. default:
  263. break;
  264. }
  265. return 0;
  266. }
  267. /**
  268. * @brief Non-blocking function for sending a command to the card.
  269. *
  270. * @param[in] cmd SDC command ID.
  271. * @param[in] arg 32-bit command argument.
  272. * @param[in] rsp_type Expected command response format.
  273. *
  274. * @retval NRF_SUCCESS If command transmission was started successfully.
  275. * @retval NRF_ERROR_BUSY If the card is not in idle state.
  276. */
  277. static ret_code_t sdc_cmd(uint8_t cmd, uint32_t arg, sdc_response_t rsp_type)
  278. {
  279. if (m_cb.state.bus_state != SDC_BUS_IDLE)
  280. {
  281. return NRF_ERROR_BUSY;
  282. }
  283. uint8_t offset = 0;
  284. m_cb.state.bus_state = SDC_BUS_CMD;
  285. if (IS_ACMD(cmd))
  286. {
  287. // ACMD is a combination of CMD55 and the requested command,
  288. // which will be placed next in the command buffer.
  289. offset = SDC_COMMAND_LEN;
  290. m_cb.state.bus_state = SDC_BUS_ACMD;
  291. m_cb.cmd_buf[SDC_COMMAND_POS] = CMD55;
  292. m_cb.cmd_buf[SDC_COMMAND_ARG_POS] = 0;
  293. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1] = 0;
  294. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2] = 0;
  295. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3] = 0;
  296. m_cb.cmd_buf[SDC_COMMAND_CRC_POS] = SDC_CRC_DUMMY;
  297. }
  298. m_cb.cmd_buf[SDC_COMMAND_POS + offset] = cmd & SDC_COMMAND_MASK;
  299. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + offset] = (uint8_t)(arg >> 24);
  300. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1 + offset] = (uint8_t)(arg >> 16);
  301. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2 + offset] = (uint8_t)(arg >> 8);
  302. m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3 + offset] = (uint8_t)(arg);
  303. // Use predefined CRC values and omit the crc calculation if not required.
  304. uint8_t crc;
  305. switch (cmd)
  306. {
  307. case CMD0:
  308. crc = SDC_CRC_CMD0;
  309. break;
  310. case CMD8:
  311. crc = SDC_CRC_CMD8;
  312. break;
  313. default:
  314. crc = SDC_CRC_DUMMY;
  315. break;
  316. }
  317. m_cb.cmd_buf[SDC_COMMAND_CRC_POS + offset] = crc;
  318. switch (rsp_type)
  319. {
  320. case SDC_R3:
  321. m_cb.state.rsp_len = SDC_R3_LEN;
  322. break;
  323. case SDC_R7:
  324. m_cb.state.rsp_len = SDC_R7_LEN;
  325. break;
  326. default:
  327. m_cb.state.rsp_len = SDC_R1_LEN;
  328. break;
  329. }
  330. uint8_t response_len = (IS_ACMD(cmd)) ? SDC_R1_LEN : m_cb.state.rsp_len;
  331. sdc_spi_transfer(m_cb.cmd_buf,
  332. SDC_COMMAND_LEN,
  333. m_cb.rsp_buf,
  334. SDC_COMMAND_LEN + SDC_MAX_NCR + response_len);
  335. return NRF_SUCCESS;
  336. }
  337. /**
  338. * @brief Data block read subroutine.
  339. *
  340. * @param[in] p_rx_data Pointer to the data received in last transation.
  341. * @param[in] rx_length Received data length.
  342. * @param[in] block_len Size of a data block to read.
  343. * @param[out] p_exit_code Pointer to the subroutine exit code variable. Valid only if the thread has exited.
  344. *
  345. * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
  346. */
  347. static PT_THREAD(sdc_pt_sub_data_read(uint8_t * p_rx_data,
  348. uint8_t rx_length,
  349. uint16_t block_len,
  350. sdc_result_t * p_exit_code))
  351. {
  352. PT_BEGIN(SDC_PT_SUB);
  353. while (1)
  354. {
  355. ASSERT(block_len);
  356. ASSERT(m_cb.state.rw_op.block_count);
  357. m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
  358. while (m_cb.state.rw_op.blocks_left)
  359. {
  360. m_cb.state.retry_count = 0;
  361. m_cb.cmd_buf[0] = 0xFF;
  362. m_cb.state.rw_op.position = 0;
  363. m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
  364. while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
  365. {
  366. ++m_cb.state.retry_count;
  367. if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
  368. {
  369. SDC_BREAK(SDC_PT_SUB, SDC_ERROR_TIMEOUT);
  370. }
  371. // Search for the first token.
  372. while (rx_length && p_rx_data[0] == SDC_EMPTY_BYTE)
  373. {
  374. ++p_rx_data;
  375. --rx_length;
  376. }
  377. if (rx_length)
  378. {
  379. // A token has been found.
  380. if (p_rx_data[0] == SDC_TOKEN_START_BLOCK)
  381. {
  382. // Expected data start token found.
  383. // Copy the data bytes left in rx buffer into user buffer.
  384. ++p_rx_data;
  385. --rx_length;
  386. m_cb.state.bus_state = SDC_BUS_DATA;
  387. uint16_t copy_len = (rx_length > block_len) ? block_len : rx_length;
  388. for (uint32_t i = 0; i < copy_len; ++i)
  389. {
  390. m_cb.state.rw_op.buffer[i] = p_rx_data[i];
  391. }
  392. m_cb.state.rw_op.position = copy_len;
  393. m_cb.state.rw_op.buffer += copy_len;
  394. }
  395. else
  396. {
  397. // Data error.
  398. SDC_BREAK(SDC_PT_SUB, SDC_ERROR_DATA);
  399. }
  400. }
  401. else
  402. {
  403. // Continue transfer until token is received.
  404. sdc_spi_transfer(m_cb.cmd_buf, 1, m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
  405. PT_YIELD(SDC_PT_SUB);
  406. }
  407. }
  408. while (m_cb.state.rw_op.position < block_len)
  409. {
  410. {
  411. uint16_t chunk_size = block_len - m_cb.state.rw_op.position;
  412. if (chunk_size > SDC_SPI_MTU)
  413. {
  414. chunk_size = SDC_SPI_MTU;
  415. }
  416. sdc_spi_transfer(m_cb.cmd_buf, 1,
  417. m_cb.state.rw_op.buffer, chunk_size);
  418. m_cb.state.rw_op.buffer += chunk_size;
  419. m_cb.state.rw_op.position += chunk_size;
  420. }
  421. PT_YIELD(SDC_PT_SUB);
  422. }
  423. // Get the CRC.
  424. --m_cb.state.rw_op.blocks_left;
  425. sdc_spi_transfer(m_cb.cmd_buf, 1,
  426. m_cb.rsp_buf, 2);
  427. PT_YIELD(SDC_PT_SUB);
  428. // Set rx length to 0 to force "busy check" transmission before next data block.
  429. rx_length = 0;
  430. }
  431. // Send padding bytes.
  432. m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
  433. sdc_spi_transfer(m_cb.cmd_buf, 1,
  434. m_cb.rsp_buf, 2);
  435. PT_YIELD(SDC_PT_SUB);
  436. m_cb.state.bus_state = SDC_BUS_IDLE;
  437. SDC_BREAK(SDC_PT_SUB, SDC_SUCCESS);
  438. }
  439. PT_END(SDC_PT_SUB)
  440. }
  441. /**
  442. * @brief Card identification co-routine.
  443. *
  444. * @param[in] p_rx_data Pointer to the data received in last transation.
  445. * @param[in] rx_length Received data length.
  446. * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
  447. *
  448. * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
  449. */
  450. static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data,
  451. uint8_t rx_length,
  452. sdc_result_t * p_exit_code))
  453. {
  454. uint8_t r1 = p_rx_data[0];
  455. uint32_t rsp = ((uint32_t)p_rx_data[1] << 24)
  456. | ((uint32_t)p_rx_data[2] << 16)
  457. | ((uint32_t)p_rx_data[3] << 8)
  458. | ((uint32_t)p_rx_data[4]);
  459. uint32_t arg;
  460. ret_code_t err_code;
  461. sdc_result_t sub_exit_code;
  462. PT_BEGIN(SDC_PT);
  463. while (1)
  464. {
  465. err_code = sdc_cmd(CMD0, 0, SDC_R1);
  466. APP_ERROR_CHECK(err_code);
  467. PT_YIELD(SDC_PT);
  468. err_code = sdc_cmd(CMD0, 0, SDC_R1);
  469. APP_ERROR_CHECK(err_code);
  470. PT_YIELD(SDC_PT);
  471. SDC_RESP_CHECK(SDC_PT, r1);
  472. // Send CMD8 with fixed argument - 0x01AA.
  473. err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7);
  474. APP_ERROR_CHECK(err_code);
  475. PT_YIELD(SDC_PT);
  476. if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND))
  477. {
  478. // CMD8 was accepted - SD v2 card.
  479. m_cb.info.type.version = SDC_TYPE_SDV2;
  480. SDC_RESP_CHECK(SDC_PT, r1);
  481. }
  482. m_cb.state.retry_count = 0;
  483. arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
  484. err_code = sdc_cmd(ACMD41, arg, SDC_R3);
  485. APP_ERROR_CHECK(err_code);
  486. PT_YIELD(SDC_PT);
  487. if (r1 & SDC_FLAG_ILLEGAL_COMMAND)
  488. {
  489. // ACMD41 was rejected - MMC card.
  490. m_cb.info.type.version = SDC_TYPE_MMCV3;
  491. r1 &= ~SDC_FLAG_ILLEGAL_COMMAND;
  492. do
  493. {
  494. ++m_cb.state.retry_count;
  495. if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
  496. {
  497. SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
  498. }
  499. err_code = sdc_cmd(CMD1, 0, SDC_R3);
  500. APP_ERROR_CHECK(err_code);
  501. PT_YIELD(SDC_PT);
  502. SDC_RESP_CHECK(SDC_PT, r1);
  503. }
  504. while (r1 & SDC_FLAG_IN_IDLE_STATE);
  505. }
  506. else
  507. {
  508. // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready.
  509. SDC_RESP_CHECK(SDC_PT, r1);
  510. while (r1 & SDC_FLAG_IN_IDLE_STATE)
  511. {
  512. ++m_cb.state.retry_count;
  513. if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
  514. {
  515. SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
  516. }
  517. arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
  518. err_code = sdc_cmd(ACMD41, arg, SDC_R3);
  519. APP_ERROR_CHECK(err_code);
  520. PT_YIELD(SDC_PT);
  521. SDC_RESP_CHECK(SDC_PT, r1);
  522. }
  523. err_code = sdc_cmd(CMD58, 0, SDC_R3);
  524. APP_ERROR_CHECK(err_code);
  525. PT_YIELD(SDC_PT);
  526. SDC_RESP_CHECK(SDC_PT, r1);
  527. if (rsp & SDC_HCS_FLAG_MASK)
  528. {
  529. m_cb.info.type.sdhc = 1;
  530. }
  531. }
  532. if (m_cb.info.type.version != SDC_TYPE_SDV2)
  533. {
  534. // Set block length to 512 (SDv1 and MMC cards only.)
  535. err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1);
  536. APP_ERROR_CHECK(err_code);
  537. PT_YIELD(SDC_PT);
  538. SDC_RESP_CHECK(SDC_PT, r1);
  539. }
  540. // Setup the read operation and get the contents of 128-bit CSD register.
  541. m_cb.state.rw_op.buffer = m_cb.work_buf;
  542. m_cb.state.rw_op.block_count = 1;
  543. err_code = sdc_cmd(CMD9, 0, SDC_R1);
  544. APP_ERROR_CHECK(err_code);
  545. PT_YIELD(SDC_PT);
  546. SDC_RESP_CHECK(SDC_PT, r1);
  547. p_rx_data += SDC_R1_LEN;
  548. rx_length -= SDC_R1_LEN;
  549. PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \
  550. 16, &sub_exit_code));
  551. SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
  552. m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf);
  553. m_cb.info.block_len = SDC_SECTOR_SIZE;
  554. SDC_BREAK(SDC_PT, SDC_SUCCESS);
  555. }
  556. PT_END(SDC_PT)
  557. }
  558. /**
  559. * @brief Data read co-routine.
  560. *
  561. * @param[in] p_rx_data Pointer to the data received in last transaction.
  562. * @param[in] rx_length Received data length.
  563. * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
  564. *
  565. * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
  566. */
  567. static PT_THREAD(sdc_pt_read(uint8_t * p_rx_data,
  568. uint8_t rx_length,
  569. sdc_result_t * p_exit_code))
  570. {
  571. uint8_t r1;
  572. ret_code_t err_code;
  573. sdc_result_t sub_exit_code;
  574. PT_BEGIN(SDC_PT);
  575. while (1)
  576. {
  577. r1 = p_rx_data[0];
  578. SDC_RESP_CHECK(SDC_PT, r1);
  579. p_rx_data += SDC_R1_LEN;
  580. rx_length -= SDC_R1_LEN;
  581. // Run the block read subroutine.
  582. PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length,
  583. SDC_SECTOR_SIZE,
  584. &sub_exit_code));
  585. SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
  586. if (m_cb.state.rw_op.block_count > 1)
  587. {
  588. // Send the STOP_TRANSMISSION command in multiple block read mode.
  589. err_code = sdc_cmd(CMD12, 0, SDC_R1);
  590. APP_ERROR_CHECK(err_code);
  591. PT_YIELD(SDC_PT);
  592. }
  593. SDC_BREAK(SDC_PT, SDC_SUCCESS);
  594. }
  595. PT_END(SDC_PT)
  596. }
  597. /**
  598. * @brief Data write co-routine.
  599. *
  600. * @param[in] p_rx_data Pointer to the data received in last transation.
  601. * @param[in] rx_length Received data length.
  602. * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
  603. *
  604. * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
  605. */
  606. static PT_THREAD(sdc_pt_write(uint8_t * rx_data,
  607. uint8_t rx_length,
  608. sdc_result_t * p_exit_code))
  609. {
  610. ret_code_t err_code;
  611. PT_BEGIN(SDC_PT);
  612. while (1)
  613. {
  614. uint8_t r1;
  615. r1 = rx_data[0];
  616. SDC_RESP_CHECK(SDC_PT, r1);
  617. if (m_cb.info.type.version != SDC_TYPE_MMCV3 && m_cb.state.rw_op.block_count > 1)
  618. {
  619. err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
  620. APP_ERROR_CHECK(err_code);
  621. PT_YIELD(SDC_PT);
  622. r1 = rx_data[0];
  623. SDC_RESP_CHECK(SDC_PT, r1);
  624. }
  625. m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
  626. while (m_cb.state.rw_op.blocks_left)
  627. {
  628. m_cb.state.rw_op.position = 0;
  629. m_cb.state.bus_state = SDC_BUS_DATA;
  630. // Send block start token.
  631. m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
  632. m_cb.cmd_buf[1] = (m_cb.state.rw_op.block_count > 1) ? SDC_TOKEN_START_BLOCK_MULT
  633. : SDC_TOKEN_START_BLOCK;
  634. sdc_spi_transfer(m_cb.cmd_buf, 2, m_cb.rsp_buf, 2);
  635. PT_YIELD(SDC_PT);
  636. // Send the data block.
  637. while (m_cb.state.rw_op.position < SDC_SECTOR_SIZE)
  638. {
  639. {
  640. uint16_t chunk_size = SDC_SECTOR_SIZE - m_cb.state.rw_op.position;
  641. if (chunk_size > SDC_SPI_MTU)
  642. {
  643. chunk_size = SDC_SPI_MTU;
  644. }
  645. sdc_spi_transfer(&m_cb.state.rw_op.buffer[m_cb.state.rw_op.position],
  646. chunk_size,
  647. m_cb.rsp_buf,
  648. 1);
  649. m_cb.state.rw_op.position += chunk_size;
  650. }
  651. PT_YIELD(SDC_PT);
  652. }
  653. m_cb.state.rw_op.buffer += SDC_SECTOR_SIZE;
  654. // Send the dummy CRC (2 bytes) and receive data response token (1 byte).
  655. m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
  656. sdc_spi_transfer(m_cb.cmd_buf, 1,
  657. m_cb.rsp_buf, 3);
  658. PT_YIELD(SDC_PT);
  659. {
  660. uint8_t token = m_cb.rsp_buf[2] & SDC_TOKEN_DATA_RESP_MASK;
  661. if (token != SDC_TOKEN_DATA_RESP_ACCEPTED)
  662. {
  663. if (token == SDC_TOKEN_DATA_RESP_CRC_ERR
  664. || token == SDC_TOKEN_DATA_RESP_DATA_ERR)
  665. {
  666. SDC_BREAK(SDC_PT, SDC_ERROR_DATA);
  667. }
  668. else
  669. {
  670. SDC_BREAK(SDC_PT, SDC_ERROR_COMMUNICATION);
  671. }
  672. }
  673. }
  674. // Wait for the card to complete the write process.
  675. m_cb.state.retry_count = 0;
  676. while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
  677. {
  678. ++m_cb.state.retry_count;
  679. if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
  680. {
  681. SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
  682. }
  683. sdc_spi_transfer(m_cb.cmd_buf, 1,
  684. m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
  685. PT_YIELD(SDC_PT);
  686. for (uint32_t i = 0; i < rx_length; ++i)
  687. {
  688. if (rx_data[i] != 0x00)
  689. {
  690. m_cb.state.bus_state = SDC_BUS_IDLE;
  691. break;
  692. }
  693. }
  694. }
  695. --m_cb.state.rw_op.blocks_left;
  696. }
  697. if (m_cb.state.rw_op.block_count > 1)
  698. {
  699. // Send STOP_TRAN token + padding byte when writing multiple blocks.
  700. m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
  701. m_cb.cmd_buf[1] = SDC_TOKEN_STOP_TRAN;
  702. sdc_spi_transfer(m_cb.cmd_buf, 2,
  703. m_cb.rsp_buf, 3);
  704. PT_YIELD(SDC_PT);
  705. m_cb.state.retry_count = 0;
  706. m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
  707. // Wait for the card to complete the write process.
  708. while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
  709. {
  710. ++m_cb.state.retry_count;
  711. if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
  712. {
  713. SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
  714. }
  715. sdc_spi_transfer(m_cb.cmd_buf, 1,
  716. m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
  717. PT_YIELD(SDC_PT);
  718. for (uint32_t i = 0; i < rx_length; ++i)
  719. {
  720. if (rx_data[i] != 0x00)
  721. {
  722. m_cb.state.bus_state = SDC_BUS_IDLE;
  723. break;
  724. }
  725. }
  726. }
  727. }
  728. SDC_BREAK(SDC_PT, SDC_SUCCESS);
  729. }
  730. PT_END(SDC_PT)
  731. }
  732. /**
  733. * @brief SPI event handler.
  734. *
  735. * @param[in] p_event Pointer to the SPI event structure.
  736. */
  737. static void spi_handler(nrf_drv_spi_evt_t const * p_event,
  738. void * p_context)
  739. {
  740. uint8_t * rx_data = p_event->data.done.p_rx_buffer;
  741. uint8_t rx_length = p_event->data.done.rx_length;
  742. if (!m_cb.state.rw_op.blocks_left)
  743. {
  744. // Deassert CS pin if not in active data transfer.
  745. SDC_CS_DEASSERT();
  746. }
  747. if (m_cb.state.bus_state == SDC_BUS_ACMD || m_cb.state.bus_state == SDC_BUS_CMD)
  748. {
  749. // Find the beginning of a response.
  750. ASSERT(rx_length > SDC_COMMAND_LEN);
  751. rx_length -= SDC_COMMAND_LEN;
  752. rx_data += SDC_COMMAND_LEN;
  753. if (p_event->data.done.p_tx_buffer[0] == CMD12)
  754. {
  755. // Ignore the first byte if CMD12 was sent.
  756. if (rx_length)
  757. {
  758. --rx_length;
  759. ++rx_data;
  760. }
  761. }
  762. while (rx_length && rx_data[0] == SDC_EMPTY_BYTE)
  763. {
  764. --rx_length;
  765. ++rx_data;
  766. }
  767. if (rx_length == 0)
  768. {
  769. if (p_event->data.done.p_tx_buffer[0] == CMD12)
  770. {
  771. // Ignore invalid reply on CMD12.
  772. ++rx_length;
  773. --rx_data;
  774. }
  775. else
  776. {
  777. rx_data = NULL;
  778. }
  779. }
  780. if (!rx_data && m_cb.state.op != SDC_OP_RESET)
  781. {
  782. // Command response missing.
  783. sdc_evt_t evt;
  784. evt.result = SDC_ERROR_NOT_RESPONDING;
  785. switch (m_cb.state.op)
  786. {
  787. case SDC_OP_RESET:
  788. case SDC_OP_IDENTIFICATION:
  789. evt.type = SDC_EVT_INIT;
  790. m_cb.state.op = SDC_OP_IDLE;
  791. APP_ERROR_CHECK(app_sdc_uninit());
  792. break;
  793. case SDC_OP_READ:
  794. evt.type = SDC_EVT_READ;
  795. break;
  796. case SDC_OP_WRITE:
  797. evt.type = SDC_EVT_WRITE;
  798. break;
  799. default:
  800. APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
  801. break;
  802. }
  803. SDC_CS_DEASSERT();
  804. m_cb.state.op = SDC_OP_IDLE;
  805. m_cb.handler(&evt);
  806. return;
  807. }
  808. if (m_cb.state.bus_state == SDC_BUS_ACMD)
  809. {
  810. // Check the status of CMD55 and send the scheduled command if no errors has been reported.
  811. m_cb.state.bus_state = SDC_BUS_CMD;
  812. uint8_t r1 = rx_data[0];
  813. if (!(r1 & (~SDC_FLAG_IN_IDLE_STATE)))
  814. {
  815. sdc_spi_transfer(m_cb.cmd_buf + SDC_COMMAND_LEN, SDC_COMMAND_LEN,
  816. m_cb.rsp_buf, SDC_COMMAND_LEN + SDC_MAX_NCR + m_cb.state.rsp_len);
  817. return;
  818. }
  819. }
  820. m_cb.state.bus_state = SDC_BUS_IDLE;
  821. }
  822. sdc_result_t exit_code = SDC_ERROR_INTERNAL;
  823. sdc_evt_t evt;
  824. switch (m_cb.state.op)
  825. {
  826. case SDC_OP_RESET:
  827. m_cb.state.op = SDC_OP_IDENTIFICATION;
  828. PT_INIT(SDC_PT);
  829. //lint -e{616}
  830. case SDC_OP_IDENTIFICATION:
  831. if (!PT_SCHEDULE(sdc_pt_identification(rx_data, rx_length, &exit_code)))
  832. {
  833. evt.type = SDC_EVT_INIT;
  834. evt.result = exit_code;
  835. m_cb.state.op = SDC_OP_IDLE;
  836. SDC_CS_DEASSERT();
  837. if (exit_code != SDC_SUCCESS)
  838. {
  839. // Initialization process failed. Roll back to uninitialized state.
  840. APP_ERROR_CHECK(app_sdc_uninit());
  841. }
  842. sdc_spi_hispeed();
  843. m_cb.handler(&evt);
  844. }
  845. break;
  846. case SDC_OP_READ:
  847. if (!PT_SCHEDULE(sdc_pt_read(rx_data, rx_length, &exit_code)))
  848. {
  849. evt.type = SDC_EVT_READ;
  850. evt.result = exit_code;
  851. m_cb.state.op = SDC_OP_IDLE;
  852. m_cb.state.rw_op.block_count = 0;
  853. m_cb.state.rw_op.blocks_left = 0;
  854. m_cb.state.bus_state = SDC_BUS_IDLE;
  855. SDC_CS_DEASSERT();
  856. m_cb.handler(&evt);
  857. }
  858. break;
  859. case SDC_OP_WRITE:
  860. if (!PT_SCHEDULE(sdc_pt_write(rx_data, rx_length, &exit_code)))
  861. {
  862. evt.type = SDC_EVT_WRITE;
  863. evt.result = exit_code;
  864. m_cb.state.op = SDC_OP_IDLE;
  865. m_cb.state.bus_state = SDC_BUS_IDLE;
  866. m_cb.state.rw_op.block_count = 0;
  867. m_cb.state.rw_op.blocks_left = 0;
  868. SDC_CS_DEASSERT();
  869. m_cb.handler(&evt);
  870. }
  871. break;
  872. default:
  873. APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
  874. break;
  875. }
  876. return;
  877. }
  878. ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count)
  879. {
  880. ASSERT(p_buf);
  881. if (m_cb.state.op == SDC_UNINITIALIZED)
  882. {
  883. return NRF_ERROR_INVALID_STATE;
  884. }
  885. if (m_cb.state.op != SDC_OP_IDLE)
  886. {
  887. return NRF_ERROR_BUSY;
  888. }
  889. if (block_count == 0)
  890. {
  891. return NRF_ERROR_INVALID_PARAM;
  892. }
  893. m_cb.state.op = SDC_OP_READ;
  894. if (!m_cb.info.type.sdhc)
  895. {
  896. m_cb.state.rw_op.address = block_address * SDC_SECTOR_SIZE;
  897. }
  898. else
  899. {
  900. m_cb.state.rw_op.address = block_address;
  901. }
  902. m_cb.state.rw_op.buffer = p_buf;
  903. m_cb.state.rw_op.block_count = block_count;
  904. m_cb.state.rw_op.blocks_left = block_count;
  905. PT_INIT(&m_cb.state.pt);
  906. uint8_t command = (block_count > 1) ? CMD18 : CMD17;
  907. ret_code_t err_code = sdc_cmd(command, m_cb.state.rw_op.address, SDC_R1);
  908. APP_ERROR_CHECK(err_code);
  909. return NRF_SUCCESS;
  910. }
  911. ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count)
  912. {
  913. ASSERT(p_buf);
  914. if (m_cb.state.op == SDC_UNINITIALIZED)
  915. {
  916. return NRF_ERROR_INVALID_STATE;
  917. }
  918. if (m_cb.state.op != SDC_OP_IDLE)
  919. {
  920. return NRF_ERROR_BUSY;
  921. }
  922. if (block_count == 0)
  923. {
  924. return NRF_ERROR_INVALID_PARAM;
  925. }
  926. m_cb.state.op = SDC_OP_WRITE;
  927. if (!m_cb.info.type.sdhc)
  928. {
  929. m_cb.state.rw_op.address = block_address * 512uL;
  930. }
  931. else
  932. {
  933. m_cb.state.rw_op.address = block_address;
  934. }
  935. m_cb.state.rw_op.buffer = (uint8_t *) p_buf;
  936. m_cb.state.rw_op.block_count = block_count;
  937. m_cb.state.rw_op.blocks_left = block_count;
  938. PT_INIT(&m_cb.state.pt);
  939. ret_code_t err_code;
  940. if (block_count == 1)
  941. {
  942. err_code = sdc_cmd(CMD24, m_cb.state.rw_op.address, SDC_R1);
  943. APP_ERROR_CHECK(err_code);
  944. return NRF_SUCCESS;
  945. }
  946. if (m_cb.info.type.version == SDC_TYPE_MMCV3)
  947. {
  948. // Start multiple block write.
  949. err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
  950. }
  951. else
  952. {
  953. // Set pre-erase for SD cards before sending CMD25.
  954. err_code = sdc_cmd(ACMD23, block_count, SDC_R1);
  955. }
  956. APP_ERROR_CHECK(err_code);
  957. return NRF_SUCCESS;
  958. }
  959. ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler)
  960. {
  961. if (m_cb.state.op != SDC_UNINITIALIZED)
  962. {
  963. return NRF_ERROR_INVALID_STATE;
  964. }
  965. if ((!event_handler)
  966. || (p_config->cs_pin == NRF_DRV_SPI_PIN_NOT_USED)
  967. || (p_config->miso_pin == NRF_DRV_SPI_PIN_NOT_USED)
  968. || (p_config->mosi_pin == NRF_DRV_SPI_PIN_NOT_USED)
  969. || (p_config->sck_pin == NRF_DRV_SPI_PIN_NOT_USED))
  970. {
  971. return NRF_ERROR_INVALID_PARAM;
  972. }
  973. ret_code_t err_code;
  974. ASSERT(p_config->cs_pin && p_config->miso_pin
  975. && p_config->mosi_pin && p_config->sck_pin);
  976. // Configure chip select pin.
  977. m_cb.cs_pin = p_config->cs_pin;
  978. nrf_gpio_cfg_output(m_cb.cs_pin);
  979. SDC_CS_DEASSERT();
  980. const nrf_drv_spi_config_t spi_cfg = {
  981. .sck_pin = p_config->sck_pin,
  982. .mosi_pin = p_config->mosi_pin,
  983. .miso_pin = p_config->miso_pin,
  984. .ss_pin = NRF_DRV_SPI_PIN_NOT_USED,
  985. .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY,
  986. .orc = 0xFF,
  987. .frequency = (nrf_drv_spi_frequency_t) APP_SDCARD_FREQ_INIT,
  988. .mode = NRF_DRV_SPI_MODE_0,
  989. .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,
  990. };
  991. err_code = nrf_drv_spi_init(&m_spi, &spi_cfg, spi_handler, NULL);
  992. APP_ERROR_CHECK(err_code);
  993. m_cb.handler = event_handler;
  994. m_cb.state.op = SDC_OP_RESET;
  995. m_cb.info.type.version = SDC_TYPE_UNKNOWN;
  996. m_cb.info.type.sdhc = 0;
  997. m_cb.state.bus_state = SDC_BUS_IDLE;
  998. // Send 80 clocks with CS inactive to switch into SPI mode.
  999. m_cb.cmd_buf[0] = 0xFF;
  1000. err_code = nrf_drv_spi_transfer(&m_spi, m_cb.cmd_buf, 1,
  1001. m_cb.rsp_buf, 10);
  1002. APP_ERROR_CHECK(err_code);
  1003. return NRF_SUCCESS;
  1004. }
  1005. ret_code_t app_sdc_uninit(void)
  1006. {
  1007. if (m_cb.state.op == SDC_UNINITIALIZED)
  1008. {
  1009. return NRF_ERROR_INVALID_STATE;
  1010. }
  1011. if (m_cb.state.op != SDC_OP_IDLE)
  1012. {
  1013. return NRF_ERROR_BUSY;
  1014. }
  1015. nrf_drv_spi_uninit(&m_spi);
  1016. nrf_gpio_cfg_input(m_cb.cs_pin, NRF_GPIO_PIN_NOPULL);
  1017. m_cb.state.bus_state = SDC_BUS_IDLE;
  1018. m_cb.state.op = SDC_UNINITIALIZED;
  1019. return NRF_SUCCESS;
  1020. }
  1021. bool app_sdc_busy_check(void)
  1022. {
  1023. return ((m_cb.state.op != SDC_OP_IDLE) && (m_cb.state.op != SDC_UNINITIALIZED));
  1024. }
  1025. app_sdc_info_t const * app_sdc_info_get(void)
  1026. {
  1027. if (m_cb.state.op >= SDC_OP_IDLE)
  1028. {
  1029. return &m_cb.info;
  1030. }
  1031. return NULL;
  1032. }
  1033. #endif //APP_SDCARD_ENABLED