1 /*
2 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
3 * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include "sdmmc_common.h"
19
20 static const char* TAG = "sdmmc_cmd";
21
22
sdmmc_send_cmd(sdmmc_card_t * card,sdmmc_command_t * cmd)23 esp_err_t sdmmc_send_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd)
24 {
25 if (card->host.command_timeout_ms != 0) {
26 cmd->timeout_ms = card->host.command_timeout_ms;
27 } else if (cmd->timeout_ms == 0) {
28 cmd->timeout_ms = SDMMC_DEFAULT_CMD_TIMEOUT_MS;
29 }
30
31 int slot = card->host.slot;
32 ESP_LOGV(TAG, "sending cmd slot=%d op=%d arg=%x flags=%x data=%p blklen=%d datalen=%d timeout=%d",
33 slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, cmd->blklen, cmd->datalen, cmd->timeout_ms);
34 esp_err_t err = (*card->host.do_transaction)(slot, cmd);
35 if (err != 0) {
36 ESP_LOGD(TAG, "cmd=%d, sdmmc_req_run returned 0x%x", cmd->opcode, err);
37 return err;
38 }
39 int state = MMC_R1_CURRENT_STATE(cmd->response);
40 ESP_LOGV(TAG, "cmd response %08x %08x %08x %08x err=0x%x state=%d",
41 cmd->response[0],
42 cmd->response[1],
43 cmd->response[2],
44 cmd->response[3],
45 cmd->error,
46 state);
47 return cmd->error;
48 }
49
sdmmc_send_app_cmd(sdmmc_card_t * card,sdmmc_command_t * cmd)50 esp_err_t sdmmc_send_app_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd)
51 {
52 sdmmc_command_t app_cmd = {
53 .opcode = MMC_APP_CMD,
54 .flags = SCF_CMD_AC | SCF_RSP_R1,
55 .arg = MMC_ARG_RCA(card->rca),
56 };
57 esp_err_t err = sdmmc_send_cmd(card, &app_cmd);
58 if (err != ESP_OK) {
59 return err;
60 }
61 // Check APP_CMD status bit (only in SD mode)
62 if (!host_is_spi(card) && !(MMC_R1(app_cmd.response) & MMC_R1_APP_CMD)) {
63 ESP_LOGW(TAG, "card doesn't support APP_CMD");
64 return ESP_ERR_NOT_SUPPORTED;
65 }
66 return sdmmc_send_cmd(card, cmd);
67 }
68
69
sdmmc_send_cmd_go_idle_state(sdmmc_card_t * card)70 esp_err_t sdmmc_send_cmd_go_idle_state(sdmmc_card_t* card)
71 {
72 sdmmc_command_t cmd = {
73 .opcode = MMC_GO_IDLE_STATE,
74 .flags = SCF_CMD_BC | SCF_RSP_R0,
75 };
76 esp_err_t err = sdmmc_send_cmd(card, &cmd);
77 if (host_is_spi(card)) {
78 /* To enter SPI mode, CMD0 needs to be sent twice (see figure 4-1 in
79 * SD Simplified spec v4.10). Some cards enter SD mode on first CMD0,
80 * so don't expect the above command to succeed.
81 * SCF_RSP_R1 flag below tells the lower layer to expect correct R1
82 * response (in SPI mode).
83 */
84 (void) err;
85 vTaskDelay(SDMMC_GO_IDLE_DELAY_MS / portTICK_PERIOD_MS);
86
87 cmd.flags |= SCF_RSP_R1;
88 err = sdmmc_send_cmd(card, &cmd);
89 }
90 if (err == ESP_OK) {
91 vTaskDelay(SDMMC_GO_IDLE_DELAY_MS / portTICK_PERIOD_MS);
92 }
93 return err;
94 }
95
96
sdmmc_send_cmd_send_if_cond(sdmmc_card_t * card,uint32_t ocr)97 esp_err_t sdmmc_send_cmd_send_if_cond(sdmmc_card_t* card, uint32_t ocr)
98 {
99 const uint8_t pattern = 0xaa; /* any pattern will do here */
100 sdmmc_command_t cmd = {
101 .opcode = SD_SEND_IF_COND,
102 .arg = (((ocr & SD_OCR_VOL_MASK) != 0) << 8) | pattern,
103 .flags = SCF_CMD_BCR | SCF_RSP_R7,
104 };
105 esp_err_t err = sdmmc_send_cmd(card, &cmd);
106 if (err != ESP_OK) {
107 return err;
108 }
109 uint8_t response = cmd.response[0] & 0xff;
110 if (response != pattern) {
111 ESP_LOGD(TAG, "%s: received=0x%x expected=0x%x", __func__, response, pattern);
112 return ESP_ERR_INVALID_RESPONSE;
113 }
114 return ESP_OK;
115 }
116
sdmmc_send_cmd_send_op_cond(sdmmc_card_t * card,uint32_t ocr,uint32_t * ocrp)117 esp_err_t sdmmc_send_cmd_send_op_cond(sdmmc_card_t* card, uint32_t ocr, uint32_t *ocrp)
118 {
119 esp_err_t err;
120
121 sdmmc_command_t cmd = {
122 .arg = ocr,
123 .flags = SCF_CMD_BCR | SCF_RSP_R3,
124 .opcode = SD_APP_OP_COND
125 };
126 int nretries = SDMMC_SEND_OP_COND_MAX_RETRIES;
127 int err_cnt = SDMMC_SEND_OP_COND_MAX_ERRORS;
128 for (; nretries != 0; --nretries) {
129 bzero(&cmd, sizeof cmd);
130 cmd.arg = ocr;
131 cmd.flags = SCF_CMD_BCR | SCF_RSP_R3;
132 if (!card->is_mmc) { /* SD mode */
133 cmd.opcode = SD_APP_OP_COND;
134 err = sdmmc_send_app_cmd(card, &cmd);
135 } else { /* MMC mode */
136 cmd.arg &= ~MMC_OCR_ACCESS_MODE_MASK;
137 cmd.arg |= MMC_OCR_SECTOR_MODE;
138 cmd.opcode = MMC_SEND_OP_COND;
139 err = sdmmc_send_cmd(card, &cmd);
140 }
141
142 if (err != ESP_OK) {
143 if (--err_cnt == 0) {
144 ESP_LOGD(TAG, "%s: sdmmc_send_app_cmd err=0x%x", __func__, err);
145 return err;
146 } else {
147 ESP_LOGV(TAG, "%s: ignoring err=0x%x", __func__, err);
148 continue;
149 }
150 }
151 // In SD protocol, card sets MEM_READY bit in OCR when it is ready.
152 // In SPI protocol, card clears IDLE_STATE bit in R1 response.
153 if (!host_is_spi(card)) {
154 if ((MMC_R3(cmd.response) & MMC_OCR_MEM_READY) ||
155 ocr == 0) {
156 break;
157 }
158 } else {
159 if ((SD_SPI_R1(cmd.response) & SD_SPI_R1_IDLE_STATE) == 0) {
160 break;
161 }
162 }
163 vTaskDelay(10 / portTICK_PERIOD_MS);
164 }
165 if (nretries == 0) {
166 return ESP_ERR_TIMEOUT;
167 }
168 if (ocrp) {
169 *ocrp = MMC_R3(cmd.response);
170 }
171 return ESP_OK;
172 }
173
sdmmc_send_cmd_read_ocr(sdmmc_card_t * card,uint32_t * ocrp)174 esp_err_t sdmmc_send_cmd_read_ocr(sdmmc_card_t *card, uint32_t *ocrp)
175 {
176 assert(ocrp);
177 sdmmc_command_t cmd = {
178 .opcode = SD_READ_OCR,
179 .flags = SCF_CMD_BCR | SCF_RSP_R2
180 };
181 esp_err_t err = sdmmc_send_cmd(card, &cmd);
182 if (err != ESP_OK) {
183 return err;
184 }
185 *ocrp = SD_SPI_R3(cmd.response);
186 return ESP_OK;
187 }
188
189
sdmmc_send_cmd_all_send_cid(sdmmc_card_t * card,sdmmc_response_t * out_raw_cid)190 esp_err_t sdmmc_send_cmd_all_send_cid(sdmmc_card_t* card, sdmmc_response_t* out_raw_cid)
191 {
192 assert(out_raw_cid);
193 sdmmc_command_t cmd = {
194 .opcode = MMC_ALL_SEND_CID,
195 .flags = SCF_CMD_BCR | SCF_RSP_R2
196 };
197 esp_err_t err = sdmmc_send_cmd(card, &cmd);
198 if (err != ESP_OK) {
199 return err;
200 }
201 memcpy(out_raw_cid, &cmd.response, sizeof(sdmmc_response_t));
202 return ESP_OK;
203 }
204
sdmmc_send_cmd_send_cid(sdmmc_card_t * card,sdmmc_cid_t * out_cid)205 esp_err_t sdmmc_send_cmd_send_cid(sdmmc_card_t *card, sdmmc_cid_t *out_cid)
206 {
207 assert(out_cid);
208 assert(host_is_spi(card) && "SEND_CID should only be used in SPI mode");
209 assert(!card->is_mmc && "MMC cards are not supported in SPI mode");
210 sdmmc_response_t buf;
211 sdmmc_command_t cmd = {
212 .opcode = MMC_SEND_CID,
213 .flags = SCF_CMD_READ | SCF_CMD_ADTC,
214 .arg = 0,
215 .data = &buf[0],
216 .datalen = sizeof(buf)
217 };
218 esp_err_t err = sdmmc_send_cmd(card, &cmd);
219 if (err != ESP_OK) {
220 return err;
221 }
222 sdmmc_flip_byte_order(buf, sizeof(buf));
223 return sdmmc_decode_cid(buf, out_cid);
224 }
225
226
sdmmc_send_cmd_set_relative_addr(sdmmc_card_t * card,uint16_t * out_rca)227 esp_err_t sdmmc_send_cmd_set_relative_addr(sdmmc_card_t* card, uint16_t* out_rca)
228 {
229 assert(out_rca);
230 sdmmc_command_t cmd = {
231 .opcode = SD_SEND_RELATIVE_ADDR,
232 .flags = SCF_CMD_BCR | SCF_RSP_R6
233 };
234
235 /* MMC cards expect us to set the RCA.
236 * Set RCA to 1 since we don't support multiple cards on the same bus, for now.
237 */
238 uint16_t mmc_rca = 1;
239 if (card->is_mmc) {
240 cmd.arg = MMC_ARG_RCA(mmc_rca);
241 }
242
243 esp_err_t err = sdmmc_send_cmd(card, &cmd);
244 if (err != ESP_OK) {
245 return err;
246 }
247 *out_rca = (card->is_mmc) ? mmc_rca : SD_R6_RCA(cmd.response);
248 return ESP_OK;
249 }
250
sdmmc_send_cmd_set_blocklen(sdmmc_card_t * card,sdmmc_csd_t * csd)251 esp_err_t sdmmc_send_cmd_set_blocklen(sdmmc_card_t* card, sdmmc_csd_t* csd)
252 {
253 sdmmc_command_t cmd = {
254 .opcode = MMC_SET_BLOCKLEN,
255 .arg = csd->sector_size,
256 .flags = SCF_CMD_AC | SCF_RSP_R1
257 };
258 return sdmmc_send_cmd(card, &cmd);
259 }
260
sdmmc_send_cmd_send_csd(sdmmc_card_t * card,sdmmc_csd_t * out_csd)261 esp_err_t sdmmc_send_cmd_send_csd(sdmmc_card_t* card, sdmmc_csd_t* out_csd)
262 {
263 /* The trick with SEND_CSD is that in SPI mode, it acts as a data read
264 * command, while in SD mode it is an AC command with R2 response.
265 */
266 sdmmc_response_t spi_buf;
267 const bool is_spi = host_is_spi(card);
268 sdmmc_command_t cmd = {
269 .opcode = MMC_SEND_CSD,
270 .arg = is_spi ? 0 : MMC_ARG_RCA(card->rca),
271 .flags = is_spi ? (SCF_CMD_READ | SCF_CMD_ADTC | SCF_RSP_R1) :
272 (SCF_CMD_AC | SCF_RSP_R2),
273 .data = is_spi ? &spi_buf[0] : 0,
274 .datalen = is_spi ? sizeof(spi_buf) : 0,
275 };
276 esp_err_t err = sdmmc_send_cmd(card, &cmd);
277 if (err != ESP_OK) {
278 return err;
279 }
280 uint32_t* ptr = cmd.response;
281 if (is_spi) {
282 sdmmc_flip_byte_order(spi_buf, sizeof(spi_buf));
283 ptr = spi_buf;
284 }
285 if (card->is_mmc) {
286 err = sdmmc_mmc_decode_csd(cmd.response, out_csd);
287 } else {
288 err = sdmmc_decode_csd(ptr, out_csd);
289 }
290 return err;
291 }
292
sdmmc_send_cmd_select_card(sdmmc_card_t * card,uint32_t rca)293 esp_err_t sdmmc_send_cmd_select_card(sdmmc_card_t* card, uint32_t rca)
294 {
295 /* Don't expect to see a response when de-selecting a card */
296 uint32_t response = (rca == 0) ? 0 : SCF_RSP_R1;
297 sdmmc_command_t cmd = {
298 .opcode = MMC_SELECT_CARD,
299 .arg = MMC_ARG_RCA(rca),
300 .flags = SCF_CMD_AC | response
301 };
302 return sdmmc_send_cmd(card, &cmd);
303 }
304
sdmmc_send_cmd_send_scr(sdmmc_card_t * card,sdmmc_scr_t * out_scr)305 esp_err_t sdmmc_send_cmd_send_scr(sdmmc_card_t* card, sdmmc_scr_t *out_scr)
306 {
307 size_t datalen = 8;
308 uint32_t* buf = (uint32_t*) heap_caps_malloc(datalen, MALLOC_CAP_DMA);
309 if (buf == NULL) {
310 return ESP_ERR_NO_MEM;
311 }
312 sdmmc_command_t cmd = {
313 .data = buf,
314 .datalen = datalen,
315 .blklen = datalen,
316 .flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1,
317 .opcode = SD_APP_SEND_SCR
318 };
319 esp_err_t err = sdmmc_send_app_cmd(card, &cmd);
320 if (err == ESP_OK) {
321 err = sdmmc_decode_scr(buf, out_scr);
322 }
323 free(buf);
324 return err;
325 }
326
sdmmc_send_cmd_set_bus_width(sdmmc_card_t * card,int width)327 esp_err_t sdmmc_send_cmd_set_bus_width(sdmmc_card_t* card, int width)
328 {
329 sdmmc_command_t cmd = {
330 .opcode = SD_APP_SET_BUS_WIDTH,
331 .flags = SCF_RSP_R1 | SCF_CMD_AC,
332 .arg = (width == 4) ? SD_ARG_BUS_WIDTH_4 : SD_ARG_BUS_WIDTH_1,
333 };
334
335 return sdmmc_send_app_cmd(card, &cmd);
336 }
337
sdmmc_send_cmd_crc_on_off(sdmmc_card_t * card,bool crc_enable)338 esp_err_t sdmmc_send_cmd_crc_on_off(sdmmc_card_t* card, bool crc_enable)
339 {
340 assert(host_is_spi(card) && "CRC_ON_OFF can only be used in SPI mode");
341 sdmmc_command_t cmd = {
342 .opcode = SD_CRC_ON_OFF,
343 .arg = crc_enable ? 1 : 0,
344 .flags = SCF_CMD_AC | SCF_RSP_R1
345 };
346 return sdmmc_send_cmd(card, &cmd);
347 }
348
sdmmc_send_cmd_send_status(sdmmc_card_t * card,uint32_t * out_status)349 esp_err_t sdmmc_send_cmd_send_status(sdmmc_card_t* card, uint32_t* out_status)
350 {
351 sdmmc_command_t cmd = {
352 .opcode = MMC_SEND_STATUS,
353 .arg = MMC_ARG_RCA(card->rca),
354 .flags = SCF_CMD_AC | SCF_RSP_R1
355 };
356 esp_err_t err = sdmmc_send_cmd(card, &cmd);
357 if (err != ESP_OK) {
358 return err;
359 }
360 if (out_status) {
361 *out_status = MMC_R1(cmd.response);
362 }
363 return ESP_OK;
364 }
365
sdmmc_write_sectors(sdmmc_card_t * card,const void * src,size_t start_block,size_t block_count)366 esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src,
367 size_t start_block, size_t block_count)
368 {
369 esp_err_t err = ESP_OK;
370 size_t block_size = card->csd.sector_size;
371 if (esp_ptr_dma_capable(src) && (intptr_t)src % 4 == 0) {
372 err = sdmmc_write_sectors_dma(card, src, start_block, block_count);
373 } else {
374 // SDMMC peripheral needs DMA-capable buffers. Split the write into
375 // separate single block writes, if needed, and allocate a temporary
376 // DMA-capable buffer.
377 void* tmp_buf = heap_caps_malloc(block_size, MALLOC_CAP_DMA);
378 if (tmp_buf == NULL) {
379 return ESP_ERR_NO_MEM;
380 }
381 const uint8_t* cur_src = (const uint8_t*) src;
382 for (size_t i = 0; i < block_count; ++i) {
383 memcpy(tmp_buf, cur_src, block_size);
384 cur_src += block_size;
385 err = sdmmc_write_sectors_dma(card, tmp_buf, start_block + i, 1);
386 if (err != ESP_OK) {
387 ESP_LOGD(TAG, "%s: error 0x%x writing block %d+%d",
388 __func__, err, start_block, i);
389 break;
390 }
391 }
392 free(tmp_buf);
393 }
394 return err;
395 }
396
sdmmc_write_sectors_dma(sdmmc_card_t * card,const void * src,size_t start_block,size_t block_count)397 esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src,
398 size_t start_block, size_t block_count)
399 {
400 if (start_block + block_count > card->csd.capacity) {
401 return ESP_ERR_INVALID_SIZE;
402 }
403 size_t block_size = card->csd.sector_size;
404 sdmmc_command_t cmd = {
405 .flags = SCF_CMD_ADTC | SCF_RSP_R1,
406 .blklen = block_size,
407 .data = (void*) src,
408 .datalen = block_count * block_size,
409 .timeout_ms = SDMMC_WRITE_CMD_TIMEOUT_MS
410 };
411 if (block_count == 1) {
412 cmd.opcode = MMC_WRITE_BLOCK_SINGLE;
413 } else {
414 cmd.opcode = MMC_WRITE_BLOCK_MULTIPLE;
415 }
416 if (card->ocr & SD_OCR_SDHC_CAP) {
417 cmd.arg = start_block;
418 } else {
419 cmd.arg = start_block * block_size;
420 }
421 esp_err_t err = sdmmc_send_cmd(card, &cmd);
422 if (err != ESP_OK) {
423 ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err);
424 return err;
425 }
426 uint32_t status = 0;
427 size_t count = 0;
428 while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) {
429 // TODO: add some timeout here
430 err = sdmmc_send_cmd_send_status(card, &status);
431 if (err != ESP_OK) {
432 return err;
433 }
434 if (++count % 10 == 0) {
435 ESP_LOGV(TAG, "waiting for card to become ready (%d)", count);
436 }
437 }
438 return ESP_OK;
439 }
440
sdmmc_read_sectors(sdmmc_card_t * card,void * dst,size_t start_block,size_t block_count)441 esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst,
442 size_t start_block, size_t block_count)
443 {
444 esp_err_t err = ESP_OK;
445 size_t block_size = card->csd.sector_size;
446 if (esp_ptr_dma_capable(dst) && (intptr_t)dst % 4 == 0) {
447 err = sdmmc_read_sectors_dma(card, dst, start_block, block_count);
448 } else {
449 // SDMMC peripheral needs DMA-capable buffers. Split the read into
450 // separate single block reads, if needed, and allocate a temporary
451 // DMA-capable buffer.
452 void* tmp_buf = heap_caps_malloc(block_size, MALLOC_CAP_DMA);
453 if (tmp_buf == NULL) {
454 return ESP_ERR_NO_MEM;
455 }
456 uint8_t* cur_dst = (uint8_t*) dst;
457 for (size_t i = 0; i < block_count; ++i) {
458 err = sdmmc_read_sectors_dma(card, tmp_buf, start_block + i, 1);
459 if (err != ESP_OK) {
460 ESP_LOGD(TAG, "%s: error 0x%x writing block %d+%d",
461 __func__, err, start_block, i);
462 break;
463 }
464 memcpy(cur_dst, tmp_buf, block_size);
465 cur_dst += block_size;
466 }
467 free(tmp_buf);
468 }
469 return err;
470 }
471
sdmmc_read_sectors_dma(sdmmc_card_t * card,void * dst,size_t start_block,size_t block_count)472 esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst,
473 size_t start_block, size_t block_count)
474 {
475 if (start_block + block_count > card->csd.capacity) {
476 return ESP_ERR_INVALID_SIZE;
477 }
478 size_t block_size = card->csd.sector_size;
479 sdmmc_command_t cmd = {
480 .flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1,
481 .blklen = block_size,
482 .data = (void*) dst,
483 .datalen = block_count * block_size
484 };
485 if (block_count == 1) {
486 cmd.opcode = MMC_READ_BLOCK_SINGLE;
487 } else {
488 cmd.opcode = MMC_READ_BLOCK_MULTIPLE;
489 }
490 if (card->ocr & SD_OCR_SDHC_CAP) {
491 cmd.arg = start_block;
492 } else {
493 cmd.arg = start_block * block_size;
494 }
495 esp_err_t err = sdmmc_send_cmd(card, &cmd);
496 if (err != ESP_OK) {
497 ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err);
498 return err;
499 }
500 uint32_t status = 0;
501 size_t count = 0;
502 while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) {
503 // TODO: add some timeout here
504 err = sdmmc_send_cmd_send_status(card, &status);
505 if (err != ESP_OK) {
506 return err;
507 }
508 if (++count % 10 == 0) {
509 ESP_LOGV(TAG, "waiting for card to become ready (%d)", count);
510 }
511 }
512 return ESP_OK;
513 }
514