Skip to content

Commit ed7dd46

Browse files
committed
Merge branch 'feat/sdmmc_spi_no_crc_v5.3' into 'release/v5.3'
feat(sdmmc_io): support sending CMD53 with fixed address, bypass sdspi crc check (v5.3) See merge request espressif/esp-idf!31075
2 parents 44f58ec + 4e0d5c9 commit ed7dd46

File tree

4 files changed

+152
-22
lines changed

4 files changed

+152
-22
lines changed

components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/host_sdmmc/main/test_sdio_sdhost.c

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "freertos/task.h"
1515
#include "esp_timer.h"
1616
#include "ccomp_timer.h"
17+
#include "string.h"
1718

1819
#include "sdmmc_cmd.h"
1920
#include "driver/sdmmc_host.h"
@@ -43,7 +44,7 @@ typedef struct {
4344
---------------------------------------------------------------*/
4445
static sdmmc_card_t s_card;
4546

46-
static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_handle)
47+
static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_handle, sdmmc_card_t** out_card)
4748
{
4849
sdmmc_host_t host_config = (sdmmc_host_t)SDMMC_HOST_DEFAULT();
4950
host_config.flags = host_param->host_flags;
@@ -81,6 +82,10 @@ static void s_master_init(test_sdio_param_t *host_param, essl_handle_t *out_hand
8182
TEST_ESP_OK(essl_sdio_init_dev(out_handle, &essl_sdio_config));
8283

8384
TEST_ESP_OK(essl_init(*out_handle, TEST_TIMEOUT_MAX));
85+
86+
if (out_card) {
87+
*out_card = card;
88+
}
8489
}
8590

8691
static void s_master_deinit(void)
@@ -114,7 +119,7 @@ TEST_CASE("SDIO_SDMMC: test interrupt", "[sdio]")
114119
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
115120
};
116121
//essl init and sdmmc init
117-
s_master_init(&test_param, &handle);
122+
s_master_init(&test_param, &handle, NULL);
118123

119124
TEST_ESP_OK(essl_set_intr_ena(handle, TEST_INT_MASK_ALL, TEST_TIMEOUT_MAX));
120125
ret = essl_wait_int(handle, 0);
@@ -149,7 +154,7 @@ TEST_CASE("SDIO_SDMMC: test register", "[sdio]")
149154
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
150155
};
151156
//essl init and sdmmc init
152-
s_master_init(&test_param, &handle);
157+
s_master_init(&test_param, &handle, NULL);
153158

154159
uint32_t init_val = 30;
155160
srand(850);
@@ -183,7 +188,7 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
183188
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
184189
};
185190
//essl init and sdmmc init
186-
s_master_init(&test_param, &handle);
191+
s_master_init(&test_param, &handle, NULL);
187192

188193
//wait for the slave to stop, reset and start again
189194
vTaskDelay(10);
@@ -215,6 +220,66 @@ TEST_CASE("SDIO_SDMMC: test reset", "[sdio]")
215220
s_master_deinit();
216221
}
217222

223+
/*---------------------------------------------------------------
224+
SDMMC_SDIO: test fixed addr
225+
---------------------------------------------------------------*/
226+
#include "soc/soc.h"
227+
#define HOST_SLCHOST_CONF_W0_REG (DR_REG_SLCHOST_BASE + 0x6C)
228+
229+
TEST_CASE("SDIO_SDMMC: test fixed addr", "[sdio]")
230+
{
231+
essl_handle_t handle = NULL;
232+
sdmmc_card_t* card;
233+
test_sdio_param_t test_param = {
234+
.host_flags = SDMMC_HOST_FLAG_4BIT | SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF,
235+
.max_freq_khz = SDMMC_FREQ_HIGHSPEED,
236+
};
237+
//essl init and sdmmc init
238+
s_master_init(&test_param, &handle, &card);
239+
240+
vTaskDelay(10);
241+
242+
const int test_size = 128;
243+
const int write_addr = 6;
244+
uint8_t buf[test_size] = {};
245+
srand(850);
246+
for (int i = 0; i < test_size; i++) {
247+
buf[i] = rand();
248+
}
249+
ESP_LOG_BUFFER_HEX("write_val", buf, test_size);
250+
251+
TEST_ESP_OK(sdmmc_io_write_bytes(card, 1, ((HOST_SLCHOST_CONF_W0_REG + write_addr) & 0x3FF) | SDMMC_IO_FIXED_ADDR, buf, test_size));
252+
253+
const int max_size = 64;
254+
uint8_t read_buf[max_size] = {};
255+
TEST_ESP_OK(sdmmc_io_read_bytes(card, 1, HOST_SLCHOST_CONF_W0_REG & 0x3FF, read_buf, max_size));
256+
ESP_LOG_BUFFER_HEX("read_all", read_buf, max_size);
257+
for (int i = 0; i < max_size; i++) {
258+
if (i >= 24 && i < 28) {
259+
continue;
260+
}
261+
if (i >= 32 && i < 48) {
262+
continue;
263+
}
264+
if (i == write_addr) {
265+
TEST_ASSERT_EQUAL_HEX8(buf[test_size - 1], read_buf[i]);
266+
} else {
267+
TEST_ASSERT_EQUAL_HEX8(0xcc, read_buf[i]);
268+
}
269+
}
270+
271+
const int read_size = (test_size > max_size ? max_size : test_size);
272+
memset(read_buf, 0, read_size);
273+
TEST_ESP_OK(sdmmc_io_read_bytes(card, 1, ((HOST_SLCHOST_CONF_W0_REG + write_addr) & 0x3FF) | SDMMC_IO_FIXED_ADDR, read_buf, read_size));
274+
ESP_LOG_BUFFER_HEX("read_fixed", read_buf, read_size);
275+
for (int i = 0; i < read_size; i++) {
276+
TEST_ASSERT_EQUAL_HEX8(buf[test_size - 1], read_buf[i]);
277+
}
278+
279+
s_send_finish_test(handle);
280+
s_master_deinit();
281+
}
282+
218283
/*---------------------------------------------------------------
219284
Transaction Tests
220285
---------------------------------------------------------------*/
@@ -241,7 +306,7 @@ static void test_from_host(bool check_data)
241306
ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz);
242307

243308
essl_handle_t handle = NULL;
244-
s_master_init(&test_param_lists[i], &handle);
309+
s_master_init(&test_param_lists[i], &handle, NULL);
245310

246311
// Two counters are used. The `esp_timer_get_time()` is for the typical time, and the
247312
// `ccomp_timer` is for performance test to reduce influence caused by cache miss.
@@ -298,7 +363,7 @@ static void test_to_host(bool check_data)
298363
ESP_LOGI(TAG, "host speed: %"PRIu32" kHz", test_param_lists[i].max_freq_khz);
299364

300365
essl_handle_t handle = NULL;
301-
s_master_init(&test_param_lists[i], &handle);
366+
s_master_init(&test_param_lists[i], &handle, NULL);
302367

303368
esp_err_t ret;
304369
int offset = 0;

components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/main/test_sdio_slave.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,24 @@ TEST_CASE("SDIO_Slave: test reset", "[sdio]")
155155
sdio_slave_deinit();
156156
}
157157

158+
/*---------------------------------------------------------------
159+
SDMMC_SDIO: test fixed addr
160+
---------------------------------------------------------------*/
161+
TEST_CASE("SDIO_Slave: test fixed addr", "[sdio]")
162+
{
163+
s_slave_init(SDIO_SLAVE_SEND_PACKET);
164+
TEST_ESP_OK(sdio_slave_start());
165+
ESP_LOGI(TAG, "slave ready");
166+
167+
for (int i = 0; i < 64; i++) {
168+
sdio_slave_write_reg(i, 0xcc);
169+
}
170+
171+
wait_for_finish(&s_test_slv_ctx);
172+
173+
sdio_slave_stop();
174+
sdio_slave_deinit();
175+
}
158176
/*---------------------------------------------------------------
159177
Transaction Tests
160178
---------------------------------------------------------------*/

components/sdmmc/include/sdmmc_cmd.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -14,6 +14,10 @@
1414
extern "C" {
1515
#endif
1616

17+
/** Call `sdmmc_io_read_bytes`, `sdmmc_io_write_bytes`, `sdmmc_io_read_blocks` or `sdmmc_io_write_bocks` APIs with
18+
* address ORed by this flag to send CMD53 with OP Code clear (fixed address) */
19+
#define SDMMC_IO_FIXED_ADDR BIT(31)
20+
1721
/**
1822
* Probe and initialize SD/MMC card using given host
1923
*
@@ -196,6 +200,9 @@ esp_err_t sdmmc_io_write_byte(sdmmc_card_t* card, uint32_t function,
196200
* This function performs read operation using CMD53 in byte mode.
197201
* For block mode, see sdmmc_io_read_blocks.
198202
*
203+
* By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with
204+
* `SDMMC_IO_FIXED_ADDR`.
205+
*
199206
* @param card pointer to card information structure previously initialized
200207
* using sdmmc_card_init
201208
* @param function IO function number
@@ -218,6 +225,9 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
218225
* This function performs write operation using CMD53 in byte mode.
219226
* For block mode, see sdmmc_io_write_blocks.
220227
*
228+
* By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with
229+
* `SDMMC_IO_FIXED_ADDR`.
230+
*
221231
* @param card pointer to card information structure previously initialized
222232
* using sdmmc_card_init
223233
* @param function IO function number
@@ -239,6 +249,9 @@ esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function,
239249
* This function performs read operation using CMD53 in block mode.
240250
* For byte mode, see sdmmc_io_read_bytes.
241251
*
252+
* By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with
253+
* `SDMMC_IO_FIXED_ADDR`.
254+
*
242255
* @param card pointer to card information structure previously initialized
243256
* using sdmmc_card_init
244257
* @param function IO function number
@@ -261,6 +274,9 @@ esp_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function,
261274
* This function performs write operation using CMD53 in block mode.
262275
* For byte mode, see sdmmc_io_write_bytes.
263276
*
277+
* By default OP Code is set (incrementing address). To send CMD53 without this bit, OR the argument `addr` with
278+
* `SDMMC_IO_FIXED_ADDR`.
279+
*
264280
* @param card pointer to card information structure previously initialized
265281
* using sdmmc_card_init
266282
* @param function IO function number

components/sdmmc/sdmmc_io.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,17 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func,
336336
esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
337337
uint32_t addr, void* dst, size_t size)
338338
{
339+
uint32_t arg = SD_ARG_CMD53_READ;
340+
bool incr_addr = true;
341+
//Extract and unset the bit used to indicate the OP Code
342+
if (addr & SDMMC_IO_FIXED_ADDR) {
343+
addr &= ~SDMMC_IO_FIXED_ADDR;
344+
incr_addr = false;
345+
}
346+
if (incr_addr) {
347+
arg |= SD_ARG_CMD53_INCREMENT;
348+
}
349+
339350
/* host quirk: SDIO transfer with length not divisible by 4 bytes
340351
* has to be split into two transfers: one with aligned length,
341352
* the other one for the remaining 1-3 bytes.
@@ -347,68 +358,88 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
347358

348359
// Note: sdmmc_io_rw_extended has an internal timeout,
349360
// typically SDMMC_DEFAULT_CMD_TIMEOUT_MS
350-
esp_err_t err = sdmmc_io_rw_extended(card, function, addr,
351-
SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT,
352-
pc_dst, will_transfer);
361+
esp_err_t err = sdmmc_io_rw_extended(card, function, addr, arg, pc_dst, will_transfer);
353362
if (unlikely(err != ESP_OK)) {
354363
return err;
355364
}
356365
pc_dst += will_transfer;
357366
size -= will_transfer;
358-
addr += will_transfer;
367+
if (incr_addr) {
368+
addr += will_transfer;
369+
}
359370
}
360371
return ESP_OK;
361372
}
362373

363374
esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function,
364375
uint32_t addr, const void* src, size_t size)
365376
{
377+
uint32_t arg = SD_ARG_CMD53_WRITE;
378+
bool incr_addr = true;
379+
//Extract and unset the bit used to indicate the OP Code
380+
if (addr & SDMMC_IO_FIXED_ADDR) {
381+
addr &= ~SDMMC_IO_FIXED_ADDR;
382+
incr_addr = false;
383+
}
384+
if (incr_addr) {
385+
arg |= SD_ARG_CMD53_INCREMENT;
386+
}
387+
366388
/* same host quirk as in sdmmc_io_read_bytes */
367389
const uint8_t *pc_src = (const uint8_t*) src;
368-
369390
while (size > 0) {
370391
size_t size_aligned = size & (~3);
371392
size_t will_transfer = size_aligned > 0 ? size_aligned : size;
372393

373394
// Note: sdmmc_io_rw_extended has an internal timeout,
374395
// typically SDMMC_DEFAULT_CMD_TIMEOUT_MS
375-
esp_err_t err = sdmmc_io_rw_extended(card, function, addr,
376-
SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT,
377-
(void*) pc_src, will_transfer);
396+
esp_err_t err = sdmmc_io_rw_extended(card, function, addr, arg, (void*) pc_src, will_transfer);
378397
if (unlikely(err != ESP_OK)) {
379398
return err;
380399
}
381400
pc_src += will_transfer;
382401
size -= will_transfer;
383-
addr += will_transfer;
402+
if (incr_addr) {
403+
addr += will_transfer;
404+
}
384405
}
385406
return ESP_OK;
386407
}
387408

388409
esp_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function,
389410
uint32_t addr, void* dst, size_t size)
390411
{
412+
uint32_t arg = SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE;
413+
//Extract and unset the bit used to indicate the OP Code (inverted logic)
414+
if (addr & SDMMC_IO_FIXED_ADDR) {
415+
arg &= ~SD_ARG_CMD53_INCREMENT;
416+
addr &= ~SDMMC_IO_FIXED_ADDR;
417+
}
418+
391419
esp_dma_mem_info_t dma_mem_info;
392420
card->host.get_dma_info(card->host.slot, &dma_mem_info);
393421
if (unlikely(!esp_dma_is_buffer_alignment_satisfied(dst, size, dma_mem_info))) {
394422
return ESP_ERR_INVALID_ARG;
395423
}
396-
return sdmmc_io_rw_extended(card, function, addr,
397-
SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE,
398-
dst, size);
424+
return sdmmc_io_rw_extended(card, function, addr, arg, dst, size);
399425
}
400426

401427
esp_err_t sdmmc_io_write_blocks(sdmmc_card_t* card, uint32_t function,
402428
uint32_t addr, const void* src, size_t size)
403429
{
430+
uint32_t arg = SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE;
431+
//Extract and unset the bit used to indicate the OP Code (inverted logic)
432+
if (addr & SDMMC_IO_FIXED_ADDR) {
433+
arg &= ~SD_ARG_CMD53_INCREMENT;
434+
addr &= ~SDMMC_IO_FIXED_ADDR;
435+
}
436+
404437
esp_dma_mem_info_t dma_mem_info;
405438
card->host.get_dma_info(card->host.slot, &dma_mem_info);
406439
if (unlikely(!esp_dma_is_buffer_alignment_satisfied(src, size, dma_mem_info))) {
407440
return ESP_ERR_INVALID_ARG;
408441
}
409-
return sdmmc_io_rw_extended(card, function, addr,
410-
SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE,
411-
(void*) src, size);
442+
return sdmmc_io_rw_extended(card, function, addr, arg, (void*) src, size);
412443
}
413444

414445
esp_err_t sdmmc_io_enable_int(sdmmc_card_t* card)

0 commit comments

Comments
 (0)