sd_spi_io.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. #include "sd_spi_io.h"
  2. #include "sector_cache.h"
  3. #include <furi.h>
  4. #include <furi_hal.h>
  5. #include <furi/core/core_defines.h>
  6. // #define SD_SPI_DEBUG 1
  7. #define TAG "SdSpi"
  8. #ifdef SD_SPI_DEBUG
  9. #define sd_spi_debug(...) FURI_LOG_I(TAG, __VA_ARGS__)
  10. #else
  11. #define sd_spi_debug(...)
  12. #endif
  13. #define SD_CMD_LENGTH 6
  14. #define SD_DUMMY_BYTE 0xFF
  15. #define SD_ANSWER_RETRY_COUNT 8
  16. #define SD_IDLE_RETRY_COUNT 100
  17. #define SD_BLOCK_SIZE 512
  18. #define FLAG_SET(x, y) (((x) & (y)) == (y))
  19. static bool sd_high_capacity = false;
  20. typedef enum {
  21. SdSpiDataResponceOK = 0x05,
  22. SdSpiDataResponceCRCError = 0x0B,
  23. SdSpiDataResponceWriteError = 0x0D,
  24. SdSpiDataResponceOtherError = 0xFF,
  25. } SdSpiDataResponce;
  26. typedef struct {
  27. uint8_t r1;
  28. uint8_t r2;
  29. uint8_t r3;
  30. uint8_t r4;
  31. uint8_t r5;
  32. } SdSpiCmdAnswer;
  33. typedef enum {
  34. SdSpiCmdAnswerTypeR1,
  35. SdSpiCmdAnswerTypeR1B,
  36. SdSpiCmdAnswerTypeR2,
  37. SdSpiCmdAnswerTypeR3,
  38. SdSpiCmdAnswerTypeR4R5,
  39. SdSpiCmdAnswerTypeR7,
  40. } SdSpiCmdAnswerType;
  41. /*
  42. SdSpiCmd and SdSpiToken use non-standard enum value names convention,
  43. because it is more convenient to look for documentation on a specific command.
  44. For example, to find out what the SD_CMD23_SET_BLOCK_COUNT command does, you need to look for
  45. SET_BLOCK_COUNT or CMD23 in the "Part 1 Physical Layer Simplified Specification".
  46. Do not use that naming convention in other places.
  47. */
  48. typedef enum {
  49. SD_CMD0_GO_IDLE_STATE = 0,
  50. SD_CMD1_SEND_OP_COND = 1,
  51. SD_CMD8_SEND_IF_COND = 8,
  52. SD_CMD9_SEND_CSD = 9,
  53. SD_CMD10_SEND_CID = 10,
  54. SD_CMD12_STOP_TRANSMISSION = 12,
  55. SD_CMD13_SEND_STATUS = 13,
  56. SD_CMD16_SET_BLOCKLEN = 16,
  57. SD_CMD17_READ_SINGLE_BLOCK = 17,
  58. SD_CMD18_READ_MULT_BLOCK = 18,
  59. SD_CMD23_SET_BLOCK_COUNT = 23,
  60. SD_CMD24_WRITE_SINGLE_BLOCK = 24,
  61. SD_CMD25_WRITE_MULT_BLOCK = 25,
  62. SD_CMD27_PROG_CSD = 27,
  63. SD_CMD28_SET_WRITE_PROT = 28,
  64. SD_CMD29_CLR_WRITE_PROT = 29,
  65. SD_CMD30_SEND_WRITE_PROT = 30,
  66. SD_CMD32_SD_ERASE_GRP_START = 32,
  67. SD_CMD33_SD_ERASE_GRP_END = 33,
  68. SD_CMD34_UNTAG_SECTOR = 34,
  69. SD_CMD35_ERASE_GRP_START = 35,
  70. SD_CMD36_ERASE_GRP_END = 36,
  71. SD_CMD37_UNTAG_ERASE_GROUP = 37,
  72. SD_CMD38_ERASE = 38,
  73. SD_CMD41_SD_APP_OP_COND = 41,
  74. SD_CMD55_APP_CMD = 55,
  75. SD_CMD58_READ_OCR = 58,
  76. } SdSpiCmd;
  77. /** Data tokens */
  78. typedef enum {
  79. SD_TOKEN_START_DATA_SINGLE_BLOCK_READ = 0xFE,
  80. SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ = 0xFE,
  81. SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE = 0xFE,
  82. SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE = 0xFC,
  83. SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE = 0xFD,
  84. } SdSpiToken;
  85. /** R1 answer value */
  86. typedef enum {
  87. SdSpi_R1_NO_ERROR = 0x00,
  88. SdSpi_R1_IN_IDLE_STATE = 0x01,
  89. SdSpi_R1_ERASE_RESET = 0x02,
  90. SdSpi_R1_ILLEGAL_COMMAND = 0x04,
  91. SdSpi_R1_COM_CRC_ERROR = 0x08,
  92. SdSpi_R1_ERASE_SEQUENCE_ERROR = 0x10,
  93. SdSpi_R1_ADDRESS_ERROR = 0x20,
  94. SdSpi_R1_PARAMETER_ERROR = 0x40,
  95. } SdSpiR1;
  96. /** R2 answer value */
  97. typedef enum {
  98. /* R2 answer value */
  99. SdSpi_R2_NO_ERROR = 0x00,
  100. SdSpi_R2_CARD_LOCKED = 0x01,
  101. SdSpi_R2_LOCKUNLOCK_ERROR = 0x02,
  102. SdSpi_R2_ERROR = 0x04,
  103. SdSpi_R2_CC_ERROR = 0x08,
  104. SdSpi_R2_CARD_ECC_FAILED = 0x10,
  105. SdSpi_R2_WP_VIOLATION = 0x20,
  106. SdSpi_R2_ERASE_PARAM = 0x40,
  107. SdSpi_R2_OUTOFRANGE = 0x80,
  108. } SdSpiR2;
  109. static inline void sd_spi_select_card() {
  110. furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false);
  111. furi_delay_us(10); // Entry guard time for some SD cards
  112. }
  113. static inline void sd_spi_deselect_card() {
  114. furi_delay_us(10); // Exit guard time for some SD cards
  115. furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
  116. }
  117. static void sd_spi_bus_to_ground() {
  118. furi_hal_gpio_init_ex(
  119. furi_hal_sd_spi_handle->miso,
  120. GpioModeOutputPushPull,
  121. GpioPullNo,
  122. GpioSpeedVeryHigh,
  123. GpioAltFnUnused);
  124. furi_hal_gpio_init_ex(
  125. furi_hal_sd_spi_handle->mosi,
  126. GpioModeOutputPushPull,
  127. GpioPullNo,
  128. GpioSpeedVeryHigh,
  129. GpioAltFnUnused);
  130. furi_hal_gpio_init_ex(
  131. furi_hal_sd_spi_handle->sck,
  132. GpioModeOutputPushPull,
  133. GpioPullNo,
  134. GpioSpeedVeryHigh,
  135. GpioAltFnUnused);
  136. sd_spi_select_card();
  137. furi_hal_gpio_write(furi_hal_sd_spi_handle->miso, false);
  138. furi_hal_gpio_write(furi_hal_sd_spi_handle->mosi, false);
  139. furi_hal_gpio_write(furi_hal_sd_spi_handle->sck, false);
  140. }
  141. static void sd_spi_bus_rise_up() {
  142. sd_spi_deselect_card();
  143. furi_hal_gpio_init_ex(
  144. furi_hal_sd_spi_handle->miso,
  145. GpioModeAltFunctionPushPull,
  146. GpioPullUp,
  147. GpioSpeedVeryHigh,
  148. GpioAltFn5SPI2);
  149. furi_hal_gpio_init_ex(
  150. furi_hal_sd_spi_handle->mosi,
  151. GpioModeAltFunctionPushPull,
  152. GpioPullUp,
  153. GpioSpeedVeryHigh,
  154. GpioAltFn5SPI2);
  155. furi_hal_gpio_init_ex(
  156. furi_hal_sd_spi_handle->sck,
  157. GpioModeAltFunctionPushPull,
  158. GpioPullUp,
  159. GpioSpeedVeryHigh,
  160. GpioAltFn5SPI2);
  161. }
  162. static inline uint8_t sd_spi_read_byte(void) {
  163. uint8_t responce;
  164. furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, NULL, &responce, 1, SD_TIMEOUT_MS));
  165. return responce;
  166. }
  167. static inline void sd_spi_write_byte(uint8_t data) {
  168. furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, &data, NULL, 1, SD_TIMEOUT_MS));
  169. }
  170. static inline uint8_t sd_spi_write_and_read_byte(uint8_t data) {
  171. uint8_t responce;
  172. furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, &data, &responce, 1, SD_TIMEOUT_MS));
  173. return responce;
  174. }
  175. static inline void sd_spi_write_bytes(uint8_t* data, uint32_t size) {
  176. furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, data, NULL, size, SD_TIMEOUT_MS));
  177. }
  178. static inline void sd_spi_read_bytes(uint8_t* data, uint32_t size) {
  179. furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, NULL, data, size, SD_TIMEOUT_MS));
  180. }
  181. static inline void sd_spi_write_bytes_dma(uint8_t* data, uint32_t size) {
  182. uint32_t timeout_mul = (size / 512) + 1;
  183. furi_check(furi_hal_spi_bus_trx_dma(
  184. furi_hal_sd_spi_handle, data, NULL, size, SD_TIMEOUT_MS * timeout_mul));
  185. }
  186. static inline void sd_spi_read_bytes_dma(uint8_t* data, uint32_t size) {
  187. uint32_t timeout_mul = (size / 512) + 1;
  188. furi_check(furi_hal_spi_bus_trx_dma(
  189. furi_hal_sd_spi_handle, NULL, data, size, SD_TIMEOUT_MS * timeout_mul));
  190. }
  191. static uint8_t sd_spi_wait_for_data_and_read(void) {
  192. uint8_t retry_count = SD_ANSWER_RETRY_COUNT;
  193. uint8_t responce;
  194. // Wait until we get a valid data
  195. do {
  196. responce = sd_spi_read_byte();
  197. retry_count--;
  198. } while((responce == SD_DUMMY_BYTE) && retry_count);
  199. return responce;
  200. }
  201. static SdSpiStatus sd_spi_wait_for_data(uint8_t data, uint32_t timeout_ms) {
  202. FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout_ms * 1000);
  203. uint8_t byte;
  204. do {
  205. byte = sd_spi_read_byte();
  206. if(furi_hal_cortex_timer_is_expired(timer)) {
  207. return SdSpiStatusTimeout;
  208. }
  209. } while((byte != data));
  210. return SdSpiStatusOK;
  211. }
  212. static inline void sd_spi_deselect_card_and_purge() {
  213. sd_spi_deselect_card();
  214. sd_spi_read_byte();
  215. }
  216. static inline void sd_spi_purge_crc() {
  217. sd_spi_read_byte();
  218. sd_spi_read_byte();
  219. }
  220. static SdSpiCmdAnswer
  221. sd_spi_send_cmd(SdSpiCmd cmd, uint32_t arg, uint8_t crc, SdSpiCmdAnswerType answer_type) {
  222. uint8_t frame[SD_CMD_LENGTH];
  223. SdSpiCmdAnswer cmd_answer = {
  224. .r1 = SD_DUMMY_BYTE,
  225. .r2 = SD_DUMMY_BYTE,
  226. .r3 = SD_DUMMY_BYTE,
  227. .r4 = SD_DUMMY_BYTE,
  228. .r5 = SD_DUMMY_BYTE,
  229. };
  230. // R1 Length = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes
  231. // R1b identical to R1 + Busy information
  232. // R2 Length = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes
  233. frame[0] = ((uint8_t)cmd | 0x40);
  234. frame[1] = (uint8_t)(arg >> 24);
  235. frame[2] = (uint8_t)(arg >> 16);
  236. frame[3] = (uint8_t)(arg >> 8);
  237. frame[4] = (uint8_t)(arg);
  238. frame[5] = (crc | 0x01);
  239. sd_spi_select_card();
  240. sd_spi_write_bytes(frame, sizeof(frame));
  241. switch(answer_type) {
  242. case SdSpiCmdAnswerTypeR1:
  243. cmd_answer.r1 = sd_spi_wait_for_data_and_read();
  244. break;
  245. case SdSpiCmdAnswerTypeR1B:
  246. // TODO: can be wrong, at least for SD_CMD12_STOP_TRANSMISSION you need to purge one byte before reading R1
  247. cmd_answer.r1 = sd_spi_wait_for_data_and_read();
  248. // In general this shenenigans seems suspicious, please double check SD specs if you are using SdSpiCmdAnswerTypeR1B
  249. // reassert card
  250. sd_spi_deselect_card();
  251. furi_delay_us(1000);
  252. sd_spi_deselect_card();
  253. // and wait for it to be ready
  254. while(sd_spi_read_byte() != 0xFF) {
  255. };
  256. break;
  257. case SdSpiCmdAnswerTypeR2:
  258. cmd_answer.r1 = sd_spi_wait_for_data_and_read();
  259. cmd_answer.r2 = sd_spi_read_byte();
  260. break;
  261. case SdSpiCmdAnswerTypeR3:
  262. case SdSpiCmdAnswerTypeR7:
  263. cmd_answer.r1 = sd_spi_wait_for_data_and_read();
  264. cmd_answer.r2 = sd_spi_read_byte();
  265. cmd_answer.r3 = sd_spi_read_byte();
  266. cmd_answer.r4 = sd_spi_read_byte();
  267. cmd_answer.r5 = sd_spi_read_byte();
  268. break;
  269. default:
  270. break;
  271. }
  272. return cmd_answer;
  273. }
  274. static SdSpiDataResponce sd_spi_get_data_response(uint32_t timeout_ms) {
  275. SdSpiDataResponce responce = sd_spi_read_byte();
  276. // read busy response byte
  277. sd_spi_read_byte();
  278. switch(responce & 0x1F) {
  279. case SdSpiDataResponceOK:
  280. // TODO: check timings
  281. sd_spi_deselect_card();
  282. sd_spi_select_card();
  283. // wait for 0xFF
  284. if(sd_spi_wait_for_data(0xFF, timeout_ms) == SdSpiStatusOK) {
  285. return SdSpiDataResponceOK;
  286. } else {
  287. return SdSpiDataResponceOtherError;
  288. }
  289. case SdSpiDataResponceCRCError:
  290. return SdSpiDataResponceCRCError;
  291. case SdSpiDataResponceWriteError:
  292. return SdSpiDataResponceWriteError;
  293. default:
  294. return SdSpiDataResponceOtherError;
  295. }
  296. }
  297. static SdSpiStatus sd_spi_init_spi_mode_v1(void) {
  298. SdSpiCmdAnswer response;
  299. uint8_t retry_count = 0;
  300. sd_spi_debug("Init SD card in SPI mode v1");
  301. do {
  302. retry_count++;
  303. // CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
  304. sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  305. sd_spi_deselect_card_and_purge();
  306. // ACMD41 (SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
  307. response = sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  308. sd_spi_deselect_card_and_purge();
  309. if(retry_count >= SD_IDLE_RETRY_COUNT) {
  310. return SdSpiStatusError;
  311. }
  312. } while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
  313. sd_spi_debug("Init SD card in SPI mode v1 done");
  314. return SdSpiStatusOK;
  315. }
  316. static SdSpiStatus sd_spi_init_spi_mode_v2(void) {
  317. SdSpiCmdAnswer response;
  318. uint8_t retry_count = 0;
  319. sd_spi_debug("Init SD card in SPI mode v2");
  320. do {
  321. retry_count++;
  322. // CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
  323. sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  324. sd_spi_deselect_card_and_purge();
  325. // ACMD41 (APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
  326. response =
  327. sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0x40000000, 0xFF, SdSpiCmdAnswerTypeR1);
  328. sd_spi_deselect_card_and_purge();
  329. if(retry_count >= SD_IDLE_RETRY_COUNT) {
  330. sd_spi_debug("ACMD41 failed");
  331. return SdSpiStatusError;
  332. }
  333. } while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
  334. if(FLAG_SET(response.r1, SdSpi_R1_ILLEGAL_COMMAND)) {
  335. sd_spi_debug("ACMD41 is illegal command");
  336. retry_count = 0;
  337. do {
  338. retry_count++;
  339. // CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
  340. response = sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  341. sd_spi_deselect_card_and_purge();
  342. if(response.r1 != SdSpi_R1_IN_IDLE_STATE) {
  343. sd_spi_debug("CMD55 failed");
  344. return SdSpiStatusError;
  345. }
  346. // ACMD41 (SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
  347. response = sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  348. sd_spi_deselect_card_and_purge();
  349. if(retry_count >= SD_IDLE_RETRY_COUNT) {
  350. sd_spi_debug("ACMD41 failed");
  351. return SdSpiStatusError;
  352. }
  353. } while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
  354. }
  355. sd_spi_debug("Init SD card in SPI mode v2 done");
  356. return SdSpiStatusOK;
  357. }
  358. static SdSpiStatus sd_spi_init_spi_mode(void) {
  359. SdSpiCmdAnswer response;
  360. uint8_t retry_count;
  361. // CMD0 (GO_IDLE_STATE) to put SD in SPI mode and
  362. // wait for In Idle State Response (R1 Format) equal to 0x01
  363. retry_count = 0;
  364. do {
  365. retry_count++;
  366. response = sd_spi_send_cmd(SD_CMD0_GO_IDLE_STATE, 0, 0x95, SdSpiCmdAnswerTypeR1);
  367. sd_spi_deselect_card_and_purge();
  368. if(retry_count >= SD_IDLE_RETRY_COUNT) {
  369. sd_spi_debug("CMD0 failed");
  370. return SdSpiStatusError;
  371. }
  372. } while(response.r1 != SdSpi_R1_IN_IDLE_STATE);
  373. // CMD8 (SEND_IF_COND) to check the power supply status
  374. // and wait until response (R7 Format) equal to 0xAA and
  375. response = sd_spi_send_cmd(SD_CMD8_SEND_IF_COND, 0x1AA, 0x87, SdSpiCmdAnswerTypeR7);
  376. sd_spi_deselect_card_and_purge();
  377. if(FLAG_SET(response.r1, SdSpi_R1_ILLEGAL_COMMAND)) {
  378. if(sd_spi_init_spi_mode_v1() != SdSpiStatusOK) {
  379. sd_spi_debug("Init mode v1 failed");
  380. return SdSpiStatusError;
  381. }
  382. sd_high_capacity = 0;
  383. } else if(response.r1 == SdSpi_R1_IN_IDLE_STATE) {
  384. if(sd_spi_init_spi_mode_v2() != SdSpiStatusOK) {
  385. sd_spi_debug("Init mode v2 failed");
  386. return SdSpiStatusError;
  387. }
  388. // CMD58 (READ_OCR) to initialize SDHC or SDXC cards: R3 response
  389. response = sd_spi_send_cmd(SD_CMD58_READ_OCR, 0, 0xFF, SdSpiCmdAnswerTypeR3);
  390. sd_spi_deselect_card_and_purge();
  391. if(response.r1 != SdSpi_R1_NO_ERROR) {
  392. sd_spi_debug("CMD58 failed");
  393. return SdSpiStatusError;
  394. }
  395. sd_high_capacity = (response.r2 & 0x40) >> 6;
  396. } else {
  397. return SdSpiStatusError;
  398. }
  399. sd_spi_debug("SD card is %s", sd_high_capacity ? "SDHC or SDXC" : "SDSC");
  400. return SdSpiStatusOK;
  401. }
  402. static SdSpiStatus sd_spi_get_csd(SD_CSD* csd) {
  403. uint16_t counter = 0;
  404. uint8_t csd_data[16];
  405. SdSpiStatus ret = SdSpiStatusError;
  406. SdSpiCmdAnswer response;
  407. // CMD9 (SEND_CSD): R1 format (0x00 is no errors)
  408. response = sd_spi_send_cmd(SD_CMD9_SEND_CSD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  409. if(response.r1 == SdSpi_R1_NO_ERROR) {
  410. if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, SD_TIMEOUT_MS) ==
  411. SdSpiStatusOK) {
  412. // read CSD data
  413. for(counter = 0; counter < 16; counter++) {
  414. csd_data[counter] = sd_spi_read_byte();
  415. }
  416. sd_spi_purge_crc();
  417. /*************************************************************************
  418. CSD header decoding
  419. *************************************************************************/
  420. csd->CSDStruct = (csd_data[0] & 0xC0) >> 6;
  421. csd->Reserved1 = csd_data[0] & 0x3F;
  422. csd->TAAC = csd_data[1];
  423. csd->NSAC = csd_data[2];
  424. csd->MaxBusClkFrec = csd_data[3];
  425. csd->CardComdClasses = (csd_data[4] << 4) | ((csd_data[5] & 0xF0) >> 4);
  426. csd->RdBlockLen = csd_data[5] & 0x0F;
  427. csd->PartBlockRead = (csd_data[6] & 0x80) >> 7;
  428. csd->WrBlockMisalign = (csd_data[6] & 0x40) >> 6;
  429. csd->RdBlockMisalign = (csd_data[6] & 0x20) >> 5;
  430. csd->DSRImpl = (csd_data[6] & 0x10) >> 4;
  431. /*************************************************************************
  432. CSD v1/v2 decoding
  433. *************************************************************************/
  434. if(sd_high_capacity == 0) {
  435. csd->version.v1.Reserved1 = ((csd_data[6] & 0x0C) >> 2);
  436. csd->version.v1.DeviceSize = ((csd_data[6] & 0x03) << 10) | (csd_data[7] << 2) |
  437. ((csd_data[8] & 0xC0) >> 6);
  438. csd->version.v1.MaxRdCurrentVDDMin = (csd_data[8] & 0x38) >> 3;
  439. csd->version.v1.MaxRdCurrentVDDMax = (csd_data[8] & 0x07);
  440. csd->version.v1.MaxWrCurrentVDDMin = (csd_data[9] & 0xE0) >> 5;
  441. csd->version.v1.MaxWrCurrentVDDMax = (csd_data[9] & 0x1C) >> 2;
  442. csd->version.v1.DeviceSizeMul = ((csd_data[9] & 0x03) << 1) |
  443. ((csd_data[10] & 0x80) >> 7);
  444. } else {
  445. csd->version.v2.Reserved1 = ((csd_data[6] & 0x0F) << 2) |
  446. ((csd_data[7] & 0xC0) >> 6);
  447. csd->version.v2.DeviceSize = ((csd_data[7] & 0x3F) << 16) | (csd_data[8] << 8) |
  448. csd_data[9];
  449. csd->version.v2.Reserved2 = ((csd_data[10] & 0x80) >> 8);
  450. }
  451. csd->EraseSingleBlockEnable = (csd_data[10] & 0x40) >> 6;
  452. csd->EraseSectorSize = ((csd_data[10] & 0x3F) << 1) | ((csd_data[11] & 0x80) >> 7);
  453. csd->WrProtectGrSize = (csd_data[11] & 0x7F);
  454. csd->WrProtectGrEnable = (csd_data[12] & 0x80) >> 7;
  455. csd->Reserved2 = (csd_data[12] & 0x60) >> 5;
  456. csd->WrSpeedFact = (csd_data[12] & 0x1C) >> 2;
  457. csd->MaxWrBlockLen = ((csd_data[12] & 0x03) << 2) | ((csd_data[13] & 0xC0) >> 6);
  458. csd->WriteBlockPartial = (csd_data[13] & 0x20) >> 5;
  459. csd->Reserved3 = (csd_data[13] & 0x1F);
  460. csd->FileFormatGrouop = (csd_data[14] & 0x80) >> 7;
  461. csd->CopyFlag = (csd_data[14] & 0x40) >> 6;
  462. csd->PermWrProtect = (csd_data[14] & 0x20) >> 5;
  463. csd->TempWrProtect = (csd_data[14] & 0x10) >> 4;
  464. csd->FileFormat = (csd_data[14] & 0x0C) >> 2;
  465. csd->Reserved4 = (csd_data[14] & 0x03);
  466. csd->crc = (csd_data[15] & 0xFE) >> 1;
  467. csd->Reserved5 = (csd_data[15] & 0x01);
  468. ret = SdSpiStatusOK;
  469. }
  470. }
  471. sd_spi_deselect_card_and_purge();
  472. return ret;
  473. }
  474. static SdSpiStatus sd_spi_get_cid(SD_CID* Cid) {
  475. uint16_t counter = 0;
  476. uint8_t cid_data[16];
  477. SdSpiStatus ret = SdSpiStatusError;
  478. SdSpiCmdAnswer response;
  479. // CMD10 (SEND_CID): R1 format (0x00 is no errors)
  480. response = sd_spi_send_cmd(SD_CMD10_SEND_CID, 0, 0xFF, SdSpiCmdAnswerTypeR1);
  481. if(response.r1 == SdSpi_R1_NO_ERROR) {
  482. if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, SD_TIMEOUT_MS) ==
  483. SdSpiStatusOK) {
  484. // read CID data
  485. for(counter = 0; counter < 16; counter++) {
  486. cid_data[counter] = sd_spi_read_byte();
  487. }
  488. sd_spi_purge_crc();
  489. Cid->ManufacturerID = cid_data[0];
  490. memcpy(Cid->OEM_AppliID, cid_data + 1, 2);
  491. memcpy(Cid->ProdName, cid_data + 3, 5);
  492. Cid->ProdRev = cid_data[8];
  493. Cid->ProdSN = cid_data[9] << 24;
  494. Cid->ProdSN |= cid_data[10] << 16;
  495. Cid->ProdSN |= cid_data[11] << 8;
  496. Cid->ProdSN |= cid_data[12];
  497. Cid->Reserved1 = (cid_data[13] & 0xF0) >> 4;
  498. Cid->ManufactYear = (cid_data[13] & 0x0F) << 4;
  499. Cid->CID_CRC = (cid_data[15] & 0xFE) >> 1;
  500. Cid->Reserved2 = 1;
  501. ret = SdSpiStatusOK;
  502. }
  503. }
  504. sd_spi_deselect_card_and_purge();
  505. return ret;
  506. }
  507. static inline bool sd_cache_get(uint32_t address, uint32_t* data) {
  508. uint8_t* cached_data = sector_cache_get(address);
  509. if(cached_data) {
  510. memcpy(data, cached_data, SD_BLOCK_SIZE);
  511. return true;
  512. }
  513. return false;
  514. }
  515. static inline void sd_cache_put(uint32_t address, uint32_t* data) {
  516. sector_cache_put(address, (uint8_t*)data);
  517. }
  518. static inline void sd_cache_invalidate_range(uint32_t start_sector, uint32_t end_sector) {
  519. sector_cache_invalidate_range(start_sector, end_sector);
  520. }
  521. static SdSpiStatus
  522. sd_spi_cmd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
  523. uint32_t block_address = address;
  524. uint32_t offset = 0;
  525. // CMD16 (SET_BLOCKLEN): R1 response (0x00: no errors)
  526. SdSpiCmdAnswer response =
  527. sd_spi_send_cmd(SD_CMD16_SET_BLOCKLEN, SD_BLOCK_SIZE, 0xFF, SdSpiCmdAnswerTypeR1);
  528. sd_spi_deselect_card_and_purge();
  529. if(response.r1 != SdSpi_R1_NO_ERROR) {
  530. return SdSpiStatusError;
  531. }
  532. if(!sd_high_capacity) {
  533. block_address = address * SD_BLOCK_SIZE;
  534. }
  535. while(blocks--) {
  536. // CMD17 (READ_SINGLE_BLOCK): R1 response (0x00: no errors)
  537. response =
  538. sd_spi_send_cmd(SD_CMD17_READ_SINGLE_BLOCK, block_address, 0xFF, SdSpiCmdAnswerTypeR1);
  539. if(response.r1 != SdSpi_R1_NO_ERROR) {
  540. sd_spi_deselect_card_and_purge();
  541. return SdSpiStatusError;
  542. }
  543. // Wait for the data start token
  544. if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, timeout_ms) ==
  545. SdSpiStatusOK) {
  546. // Read the data block
  547. sd_spi_read_bytes_dma((uint8_t*)data + offset, SD_BLOCK_SIZE);
  548. sd_spi_purge_crc();
  549. // increase offset
  550. offset += SD_BLOCK_SIZE;
  551. // increase block address
  552. if(sd_high_capacity) {
  553. block_address += 1;
  554. } else {
  555. block_address += SD_BLOCK_SIZE;
  556. }
  557. } else {
  558. sd_spi_deselect_card_and_purge();
  559. return SdSpiStatusError;
  560. }
  561. sd_spi_deselect_card_and_purge();
  562. }
  563. return SdSpiStatusOK;
  564. }
  565. static SdSpiStatus sd_spi_cmd_write_blocks(
  566. uint32_t* data,
  567. uint32_t address,
  568. uint32_t blocks,
  569. uint32_t timeout_ms) {
  570. uint32_t block_address = address;
  571. uint32_t offset = 0;
  572. // CMD16 (SET_BLOCKLEN): R1 response (0x00: no errors)
  573. SdSpiCmdAnswer response =
  574. sd_spi_send_cmd(SD_CMD16_SET_BLOCKLEN, SD_BLOCK_SIZE, 0xFF, SdSpiCmdAnswerTypeR1);
  575. sd_spi_deselect_card_and_purge();
  576. if(response.r1 != SdSpi_R1_NO_ERROR) {
  577. return SdSpiStatusError;
  578. }
  579. if(!sd_high_capacity) {
  580. block_address = address * SD_BLOCK_SIZE;
  581. }
  582. while(blocks--) {
  583. // CMD24 (WRITE_SINGLE_BLOCK): R1 response (0x00: no errors)
  584. response = sd_spi_send_cmd(
  585. SD_CMD24_WRITE_SINGLE_BLOCK, block_address, 0xFF, SdSpiCmdAnswerTypeR1);
  586. if(response.r1 != SdSpi_R1_NO_ERROR) {
  587. sd_spi_deselect_card_and_purge();
  588. return SdSpiStatusError;
  589. }
  590. // Send dummy byte for NWR timing : one byte between CMD_WRITE and TOKEN
  591. // TODO: check bytes count
  592. sd_spi_write_byte(SD_DUMMY_BYTE);
  593. sd_spi_write_byte(SD_DUMMY_BYTE);
  594. // Send the data start token
  595. sd_spi_write_byte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE);
  596. sd_spi_write_bytes_dma((uint8_t*)data + offset, SD_BLOCK_SIZE);
  597. sd_spi_purge_crc();
  598. // Read data response
  599. SdSpiDataResponce data_responce = sd_spi_get_data_response(timeout_ms);
  600. sd_spi_deselect_card_and_purge();
  601. if(data_responce != SdSpiDataResponceOK) {
  602. return SdSpiStatusError;
  603. }
  604. // increase offset
  605. offset += SD_BLOCK_SIZE;
  606. // increase block address
  607. if(sd_high_capacity) {
  608. block_address += 1;
  609. } else {
  610. block_address += SD_BLOCK_SIZE;
  611. }
  612. }
  613. return SdSpiStatusOK;
  614. }
  615. uint8_t sd_max_mount_retry_count() {
  616. return 10;
  617. }
  618. SdSpiStatus sd_init(bool power_reset) {
  619. // Slow speed init
  620. furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow);
  621. furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow;
  622. // We reset card in spi_lock context, so it is safe to disturb spi bus
  623. if(power_reset) {
  624. sd_spi_debug("Power reset");
  625. // disable power and set low on all bus pins
  626. furi_hal_power_disable_external_3_3v();
  627. sd_spi_bus_to_ground();
  628. hal_sd_detect_set_low();
  629. furi_delay_ms(250);
  630. // reinit bus and enable power
  631. sd_spi_bus_rise_up();
  632. hal_sd_detect_init();
  633. furi_hal_power_enable_external_3_3v();
  634. furi_delay_ms(100);
  635. }
  636. SdSpiStatus status = SdSpiStatusError;
  637. // Send 80 dummy clocks with CS high
  638. sd_spi_deselect_card();
  639. for(uint8_t i = 0; i < 80; i++) {
  640. sd_spi_write_byte(SD_DUMMY_BYTE);
  641. }
  642. for(uint8_t i = 0; i < 128; i++) {
  643. status = sd_spi_init_spi_mode();
  644. if(status == SdSpiStatusOK) {
  645. // SD initialized and init to SPI mode properly
  646. sd_spi_debug("SD init OK after %d retries", i);
  647. break;
  648. }
  649. }
  650. furi_hal_sd_spi_handle = NULL;
  651. furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow);
  652. // Init sector cache
  653. sector_cache_init();
  654. return status;
  655. }
  656. SdSpiStatus sd_get_card_state(void) {
  657. SdSpiCmdAnswer response;
  658. // Send CMD13 (SEND_STATUS) to get SD status
  659. response = sd_spi_send_cmd(SD_CMD13_SEND_STATUS, 0, 0xFF, SdSpiCmdAnswerTypeR2);
  660. sd_spi_deselect_card_and_purge();
  661. // Return status OK if response is valid
  662. if((response.r1 == SdSpi_R1_NO_ERROR) && (response.r2 == SdSpi_R2_NO_ERROR)) {
  663. return SdSpiStatusOK;
  664. }
  665. return SdSpiStatusError;
  666. }
  667. SdSpiStatus sd_get_card_info(SD_CardInfo* card_info) {
  668. SdSpiStatus status;
  669. status = sd_spi_get_csd(&(card_info->Csd));
  670. if(status != SdSpiStatusOK) {
  671. return status;
  672. }
  673. status = sd_spi_get_cid(&(card_info->Cid));
  674. if(status != SdSpiStatusOK) {
  675. return status;
  676. }
  677. if(sd_high_capacity == 1) {
  678. card_info->LogBlockSize = 512;
  679. card_info->CardBlockSize = 512;
  680. card_info->CardCapacity = ((uint64_t)card_info->Csd.version.v2.DeviceSize + 1UL) * 1024UL *
  681. (uint64_t)card_info->LogBlockSize;
  682. card_info->LogBlockNbr = (card_info->CardCapacity) / (card_info->LogBlockSize);
  683. } else {
  684. card_info->CardCapacity = (card_info->Csd.version.v1.DeviceSize + 1);
  685. card_info->CardCapacity *= (1UL << (card_info->Csd.version.v1.DeviceSizeMul + 2));
  686. card_info->LogBlockSize = 512;
  687. card_info->CardBlockSize = 1UL << (card_info->Csd.RdBlockLen);
  688. card_info->CardCapacity *= card_info->CardBlockSize;
  689. card_info->LogBlockNbr = (card_info->CardCapacity) / (card_info->LogBlockSize);
  690. }
  691. return status;
  692. }
  693. SdSpiStatus
  694. sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
  695. SdSpiStatus status = SdSpiStatusError;
  696. bool single_sector_read = (blocks == 1);
  697. if(single_sector_read) {
  698. if(sd_cache_get(address, data)) {
  699. return SdSpiStatusOK;
  700. }
  701. status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
  702. if(status == SdSpiStatusOK) {
  703. sd_cache_put(address, data);
  704. }
  705. } else {
  706. status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
  707. }
  708. return status;
  709. }
  710. SdSpiStatus
  711. sd_write_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
  712. sd_cache_invalidate_range(address, address + blocks);
  713. SdSpiStatus status = sd_spi_cmd_write_blocks(data, address, blocks, timeout_ms);
  714. return status;
  715. }
  716. SdSpiStatus sd_get_cid(SD_CID* cid) {
  717. SdSpiStatus status;
  718. furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
  719. furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
  720. memset(cid, 0, sizeof(SD_CID));
  721. status = sd_spi_get_cid(cid);
  722. furi_hal_sd_spi_handle = NULL;
  723. furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
  724. return status;
  725. }