From 1f0931f6d1146787b7d1b3098a7ac1c33a14d6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Tue, 22 Oct 2024 15:04:42 +0200 Subject: [PATCH 1/4] fix(sdmmc): Send ACMD22 if CMD25 fails Send the number of the written write blocks (ACMD22) after write multiple blocks fails (CMD25) --- components/sdmmc/include/sd_protocol_defs.h | 2 + components/sdmmc/sdmmc_cmd.c | 42 ++++++++++++++++++--- components/sdmmc/sdmmc_common.h | 6 +++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/components/sdmmc/include/sd_protocol_defs.h b/components/sdmmc/include/sd_protocol_defs.h index 9072bd3d47..f943789dc8 100644 --- a/components/sdmmc/include/sd_protocol_defs.h +++ b/components/sdmmc/include/sd_protocol_defs.h @@ -69,6 +69,7 @@ extern "C" { /* SD application commands */ /* response type */ #define SD_APP_SET_BUS_WIDTH 6 /* R1 */ #define SD_APP_SD_STATUS 13 /* R2 */ +#define SD_APP_SEND_NUM_WR_BLOCKS 22 /* R1 */ #define SD_APP_OP_COND 41 /* R3 */ #define SD_APP_SEND_SCR 51 /* R1 */ @@ -261,6 +262,7 @@ extern "C" { #define MMC_CSD_CAPACITY(resp) ((MMC_CSD_C_SIZE((resp))+1) << \ (MMC_CSD_C_SIZE_MULT((resp))+2)) #define MMC_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3) +#define MMC_CSD_WRITE_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 21, 1) /* MMC v1 R2 response (CID) */ #define MMC_CID_MID_V1(resp) MMC_RSP_BITS((resp), 104, 24) diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index a281323ce6..9be0179148 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -409,6 +409,32 @@ esp_err_t sdmmc_send_cmd_send_status(sdmmc_card_t* card, uint32_t* out_status) return ESP_OK; } +esp_err_t sdmmc_send_cmd_num_of_written_blocks(sdmmc_card_t* card, size_t* out_num_blocks) +{ + esp_err_t err = ESP_OK; + uint32_t buf = 0; + sdmmc_command_t cmd = { + .data = &buf, + .datalen = sizeof(buf), + .buflen = sizeof(buf), + .blklen = sizeof(buf), + .flags = SCF_CMD_ADTC | SCF_RSP_R1 | SCF_CMD_READ, + .opcode = SD_APP_SEND_NUM_WR_BLOCKS + }; + + err = sdmmc_send_app_cmd(card, &cmd); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: sdmmc_send_app_cmd returned 0x%x, failed to get number of written write blocks", __func__, err); + return err; + } + + size_t result = __builtin_bswap32(buf); + if (out_num_blocks) { + *out_num_blocks = result; + } + return err; +} + esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, size_t start_block, size_t block_count) { @@ -459,11 +485,6 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, return err; } -static bool sdmmc_ready_for_data(uint32_t status) -{ - return (status & MMC_R1_READY_FOR_DATA) && (MMC_R1_CURRENT_STATE_STATUS(status) == MMC_R1_CURRENT_STATE_TRAN); -} - esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, size_t start_block, size_t block_count, size_t buffer_len) { @@ -495,6 +516,17 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, esp_err_t err_cmd13 = sdmmc_send_cmd_send_status(card, &status); if (err != ESP_OK) { + if (cmd.opcode == MMC_WRITE_BLOCK_MULTIPLE) { + if (!sdmmc_ready_for_data(status)) { + vTaskDelay(1); + } + size_t successfully_written_blocks = 0; + if (sdmmc_send_cmd_num_of_written_blocks(card, &successfully_written_blocks) == ESP_OK) { + ESP_LOGD(TAG, "%s: successfully wrote %zu blocks out of %zu", __func__, successfully_written_blocks, block_count); + } else { + ESP_LOGE(TAG, "%s: sdmmc_send_cmd_num_of_written_blocks returned 0x%x", __func__, err); + } + } if (err_cmd13 == ESP_OK) { ESP_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x, status 0x%" PRIx32, __func__, err, status); } else { diff --git a/components/sdmmc/sdmmc_common.h b/components/sdmmc/sdmmc_common.h index f326546ffe..350b1fd378 100644 --- a/components/sdmmc/sdmmc_common.h +++ b/components/sdmmc/sdmmc_common.h @@ -82,6 +82,7 @@ esp_err_t sdmmc_send_cmd_set_bus_width(sdmmc_card_t* card, int width); esp_err_t sdmmc_send_cmd_send_status(sdmmc_card_t* card, uint32_t* out_status); esp_err_t sdmmc_send_cmd_crc_on_off(sdmmc_card_t* card, bool crc_enable); esp_err_t sdmmc_send_cmd_voltage_switch(sdmmc_card_t* card); +esp_err_t sdmmc_send_cmd_num_of_written_blocks(sdmmc_card_t* card, size_t* out_num_blocks); /* Higher level functions */ esp_err_t sdmmc_enter_higher_speed_mode(sdmmc_card_t* card); @@ -166,6 +167,11 @@ static inline uint32_t get_host_ocr(float voltage) return SD_OCR_VOL_MASK; } +static inline bool sdmmc_ready_for_data(uint32_t status) +{ + return (status & MMC_R1_READY_FOR_DATA) && (MMC_R1_CURRENT_STATE_STATUS(status) == MMC_R1_CURRENT_STATE_TRAN); +} + void sdmmc_flip_byte_order(uint32_t* response, size_t size); esp_err_t sdmmc_fix_host_flags(sdmmc_card_t* card); From 68c1423cf34ccdb321ef190bb562fb1badc964c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Thu, 31 Oct 2024 00:46:48 +0100 Subject: [PATCH 2/4] fix(sdmmc): Generalize waiting for card idle to a function --- components/sdmmc/sdmmc_cmd.c | 68 +++++++++++---------------------- components/sdmmc/sdmmc_common.c | 32 ++++++++++++++++ components/sdmmc/sdmmc_common.h | 11 ++++++ 3 files changed, 66 insertions(+), 45 deletions(-) diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 9be0179148..ae8cb739a6 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -5,7 +5,6 @@ */ #include -#include "esp_timer.h" #include "sdmmc_common.h" static const char* TAG = "sdmmc_cmd"; @@ -517,8 +516,10 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, if (err != ESP_OK) { if (cmd.opcode == MMC_WRITE_BLOCK_MULTIPLE) { - if (!sdmmc_ready_for_data(status)) { - vTaskDelay(1); + if (!host_is_spi(card)) { + sdmmc_wait_for_idle(card, status); // wait for the card to be idle (in transfer state) + } else { + vTaskDelay(1); // when the host is in spi mode } size_t successfully_written_blocks = 0; if (sdmmc_send_cmd_num_of_written_blocks(card, &successfully_written_blocks) == ESP_OK) { @@ -535,30 +536,19 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, return err; } - size_t count = 0; - int64_t yield_delay_us = 100 * 1000; // initially 100ms - int64_t t0 = esp_timer_get_time(); - int64_t t1 = 0; /* SD mode: wait for the card to become idle based on R1 status */ - while (!host_is_spi(card) && !sdmmc_ready_for_data(status)) { - t1 = esp_timer_get_time(); - if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) { - ESP_LOGE(TAG, "write sectors dma - timeout"); - return ESP_ERR_TIMEOUT; - } - if (t1 - t0 > yield_delay_us) { - yield_delay_us *= 2; - vTaskDelay(1); - } - err = sdmmc_send_cmd_send_status(card, &status); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: sdmmc_send_cmd_send_status returned 0x%x", __func__, err); - return err; - } - if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", (uint32_t) count); + if (!host_is_spi(card)) { + switch (sdmmc_wait_for_idle(card, status)) { + case ESP_OK: + break; + case ESP_ERR_TIMEOUT: + ESP_LOGE(TAG, "%s: sdmmc_wait_for_idle timeout", __func__); + return ESP_ERR_TIMEOUT; + default: + return err; } } + /* SPI mode: although card busy indication is based on the busy token, * SD spec recommends that the host checks the results of programming by sending * SEND_STATUS command. Some of the conditions reported in SEND_STATUS are not @@ -665,28 +655,16 @@ esp_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst, return err; } - size_t count = 0; - int64_t yield_delay_us = 100 * 1000; // initially 100ms - int64_t t0 = esp_timer_get_time(); - int64_t t1 = 0; /* SD mode: wait for the card to become idle based on R1 status */ - while (!host_is_spi(card) && !sdmmc_ready_for_data(status)) { - t1 = esp_timer_get_time(); - if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) { - ESP_LOGE(TAG, "read sectors dma - timeout"); - return ESP_ERR_TIMEOUT; - } - if (t1 - t0 > yield_delay_us) { - yield_delay_us *= 2; - vTaskDelay(1); - } - err = sdmmc_send_cmd_send_status(card, &status); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: sdmmc_send_cmd_send_status returned 0x%x", __func__, err); - return err; - } - if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); + if (!host_is_spi(card)) { + switch (sdmmc_wait_for_idle(card, status)) { + case ESP_OK: + break; + case ESP_ERR_TIMEOUT: + ESP_LOGE(TAG, "%s: sdmmc_wait_for_idle timeout", __func__); + return ESP_ERR_TIMEOUT; + default: + return err; } } return ESP_OK; diff --git a/components/sdmmc/sdmmc_common.c b/components/sdmmc/sdmmc_common.c index 68342e41a9..88554ed7d2 100644 --- a/components/sdmmc/sdmmc_common.c +++ b/components/sdmmc/sdmmc_common.c @@ -16,6 +16,8 @@ */ #include +#include "esp_log.h" +#include "esp_timer.h" #include "sdmmc_common.h" static const char* TAG = "sdmmc_common"; @@ -415,3 +417,33 @@ uint32_t sdmmc_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_t er return sdmmc_sd_get_erase_timeout_ms(card, arg, erase_size_kb); } } + +esp_err_t sdmmc_wait_for_idle(sdmmc_card_t* card, uint32_t status) +{ + assert(!host_is_spi(card)); + esp_err_t err = ESP_OK; + size_t count = 0; + int64_t yield_delay_us = 100 * 1000; // initially 100ms + int64_t t0 = esp_timer_get_time(); + int64_t t1 = 0; + /* SD mode: wait for the card to become idle based on R1 status */ + while (!sdmmc_ready_for_data(status)) { + t1 = esp_timer_get_time(); + if (t1 - t0 > SDMMC_READY_FOR_DATA_TIMEOUT_US) { + return ESP_ERR_TIMEOUT; + } + if (t1 - t0 > yield_delay_us) { + yield_delay_us *= 2; + vTaskDelay(1); + } + err = sdmmc_send_cmd_send_status(card, &status); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: sdmmc_send_cmd_send_status returned 0x%x", __func__, err); + return err; + } + if (++count % 16 == 0) { + ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", (uint32_t) count); + } + } + return err; +} diff --git a/components/sdmmc/sdmmc_common.h b/components/sdmmc/sdmmc_common.h index 350b1fd378..53e0e6e671 100644 --- a/components/sdmmc/sdmmc_common.h +++ b/components/sdmmc/sdmmc_common.h @@ -30,6 +30,10 @@ #include "soc/soc_caps.h" #include "esp_dma_utils.h" +#ifdef __cplusplus +extern "C" { +#endif + #define SDMMC_GO_IDLE_DELAY_MS 20 #define SDMMC_IO_SEND_OP_COND_DELAY_MS 10 @@ -176,6 +180,13 @@ void sdmmc_flip_byte_order(uint32_t* response, size_t size); esp_err_t sdmmc_fix_host_flags(sdmmc_card_t* card); +// Use only with SDMMC mode (not SDSPI) +esp_err_t sdmmc_wait_for_idle(sdmmc_card_t* card, uint32_t status); + //Currently only SDIO support using this buffer. And only 512 block size is supported. #define SDMMC_IO_BLOCK_SIZE 512 esp_err_t sdmmc_allocate_aligned_buf(sdmmc_card_t* card); + +#ifdef __cplusplus +} +#endif From 2d5d2509fb68bdb5923636b74c160d7dabcb92ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Wed, 30 Oct 2024 14:05:03 +0100 Subject: [PATCH 3/4] test(sdmmc): Add test_apps test for sdmmc component --- .../components/sdmmc_tests/CMakeLists.txt | 3 +- .../sdmmc_tests/sdmmc_test_various_cmds.c | 73 +++++++++++++++++++ .../{ => include/esp_private}/sdmmc_common.h | 2 +- components/sdmmc/sdmmc_cmd.c | 2 +- components/sdmmc/sdmmc_common.c | 4 +- components/sdmmc/sdmmc_init.c | 4 +- components/sdmmc/sdmmc_io.c | 4 +- components/sdmmc/sdmmc_mmc.c | 4 +- components/sdmmc/sdmmc_sd.c | 4 +- tools/ci/check_copyright_ignore.txt | 2 +- 10 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_various_cmds.c rename components/sdmmc/{ => include/esp_private}/sdmmc_common.h (99%) diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/CMakeLists.txt b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/CMakeLists.txt index 599b9ffba3..96fe18ea96 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/CMakeLists.txt +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/CMakeLists.txt @@ -9,7 +9,8 @@ if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) "sdmmc_test_erase_sd.c" "sdmmc_test_trim_sd.c" "sdmmc_test_discard_sd.c" - "sdmmc_test_sanitize_sd.c") + "sdmmc_test_sanitize_sd.c" + "sdmmc_test_various_cmds.c") endif() set(priv_requires "sdmmc" diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_various_cmds.c b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_various_cmds.c new file mode 100644 index 0000000000..2f05d0ceca --- /dev/null +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_various_cmds.c @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" +#include +#include +#include "unity.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/sdmmc_defs.h" +#include "driver/sdmmc_host.h" +#include "sdmmc_cmd.h" +#include "esp_private/sdmmc_common.h" +#include "sdmmc_test_begin_end_sd.h" + +#if !SOC_SDMMC_HOST_SUPPORTED +#error "Targets with SDMMC host supported only" +#endif // !SOC_SDMMC_HOST_SUPPORTED + +static const char* TAG = "sdmmc_test_various_cmds"; + +static void sdmmc_write_sectors_cmd25_error_test_acmd22(sdmmc_card_t* card, uint32_t write_size) +{ + esp_err_t err = ESP_OK; + size_t block_size = (size_t)card->csd.sector_size; + size_t block_count = write_size / block_size; + void* buf = heap_caps_calloc(1, write_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(buf); + + if (!host_is_spi(card)) { + err = sdmmc_wait_for_idle(card, 0); // wait for the card to be idle (in transfer state) + if (err != ESP_OK) { + free(buf); + } + TEST_ESP_OK(err); + } + + // Try to write to the card + err = sdmmc_write_sectors(card, buf, 0, block_count); + free(buf); + TEST_ESP_OK(err); + + // Check if the number of written blocks is equal to the number ACMD22 returns + // ACMD22 is usually only called if CMD25 fails but here we call it anyway to test it + size_t sucessfully_written_blocks; + err = sdmmc_send_cmd_num_of_written_blocks(card, &sucessfully_written_blocks); + TEST_ESP_OK(err); + TEST_ASSERT_EQUAL_size_t(sucessfully_written_blocks, block_count); + ESP_LOGI(TAG, "%s: ACMD22 successfully written %zu blocks out of %zu", __func__, sucessfully_written_blocks, block_count); +} + +static void do_one_mmc_acmd22_test(int slot, int width, int freq_khz, int ddr) +{ + sdmmc_card_t card; + sdmmc_test_sd_skip_if_board_incompatible(slot, width, freq_khz, ddr); + sdmmc_test_sd_begin(slot, width, freq_khz, ddr, &card); + sdmmc_card_print_info(stdout, &card); + sdmmc_write_sectors_cmd25_error_test_acmd22(&card, 4096 * 4); + sdmmc_test_sd_end(&card); +} + +TEST_CASE("send ACMD22 after writing multiple blocks to check real number of successfully written blocks, slot 0, 1-bit", "[sdmmc]") +{ + do_one_mmc_acmd22_test(SLOT_0, 1, SDMMC_FREQ_HIGHSPEED, NO_DDR); +} + +TEST_CASE("send ACMD22 after writing multiple blocks to check real number of successfully written blocks, slot 1, 1-bit", "[sdmmc]") +{ + do_one_mmc_acmd22_test(SLOT_1, 1, SDMMC_FREQ_HIGHSPEED, NO_DDR); +} diff --git a/components/sdmmc/sdmmc_common.h b/components/sdmmc/include/esp_private/sdmmc_common.h similarity index 99% rename from components/sdmmc/sdmmc_common.h rename to components/sdmmc/include/esp_private/sdmmc_common.h index 53e0e6e671..be8bb7ff4b 100644 --- a/components/sdmmc/sdmmc_common.h +++ b/components/sdmmc/include/esp_private/sdmmc_common.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index ae8cb739a6..3f633adb19 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -5,7 +5,7 @@ */ #include -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" static const char* TAG = "sdmmc_cmd"; diff --git a/components/sdmmc/sdmmc_common.c b/components/sdmmc/sdmmc_common.c index 88554ed7d2..169a95dd9b 100644 --- a/components/sdmmc/sdmmc_common.c +++ b/components/sdmmc/sdmmc_common.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +18,7 @@ #include #include "esp_log.h" #include "esp_timer.h" -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" static const char* TAG = "sdmmc_common"; diff --git a/components/sdmmc/sdmmc_init.c b/components/sdmmc/sdmmc_init.c index cd8a517e92..3e62209d36 100644 --- a/components/sdmmc/sdmmc_init.c +++ b/components/sdmmc/sdmmc_init.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" #include "sd_pwr_ctrl_by_on_chip_ldo.h" #include "sd_pwr_ctrl.h" diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 970657dfe1..64492f2da3 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ #include -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" #include "esp_attr.h" #include "esp_compiler.h" diff --git a/components/sdmmc/sdmmc_mmc.c b/components/sdmmc/sdmmc_mmc.c index 5662462aa2..a4fed8a4c9 100644 --- a/components/sdmmc/sdmmc_mmc.c +++ b/components/sdmmc/sdmmc_mmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,7 +17,7 @@ #include #include -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" static const char* TAG = "sdmmc_mmc"; diff --git a/components/sdmmc/sdmmc_sd.c b/components/sdmmc/sdmmc_sd.c index d9f5564acb..45b13beb6e 100644 --- a/components/sdmmc/sdmmc_sd.c +++ b/components/sdmmc/sdmmc_sd.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD + * Adaptations to ESP-IDF Copyright (c) 2016-2024 Espressif Systems (Shanghai) PTE LTD * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,7 @@ #include "esp_check.h" #include "esp_timer.h" #include "esp_cache.h" -#include "sdmmc_common.h" +#include "esp_private/sdmmc_common.h" static const char* TAG = "sdmmc_sd"; diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index dced1b1ab5..712e7b5791 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -503,8 +503,8 @@ components/protocomm/include/transports/protocomm_console.h components/protocomm/include/transports/protocomm_httpd.h components/riscv/include/riscv/csr.h components/riscv/include/riscv/encoding.h +components/sdmmc/include/esp_private/sdmmc_common.h components/sdmmc/sdmmc_common.c -components/sdmmc/sdmmc_common.h components/sdmmc/sdmmc_init.c components/sdmmc/sdmmc_io.c components/sdmmc/sdmmc_mmc.c From 94aa1c0d5d4ed59846145b4db2427a7b4e211467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Mon, 11 Nov 2024 14:03:53 +0100 Subject: [PATCH 4/4] fix(sdmmc): Fix ACMD22 DMA buffer problem for ESP32-P4 --- components/sdmmc/sdmmc_cmd.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 3f633adb19..71f23ec756 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -410,27 +410,38 @@ esp_err_t sdmmc_send_cmd_send_status(sdmmc_card_t* card, uint32_t* out_status) esp_err_t sdmmc_send_cmd_num_of_written_blocks(sdmmc_card_t* card, size_t* out_num_blocks) { + size_t datalen = sizeof(uint32_t); esp_err_t err = ESP_OK; - uint32_t buf = 0; + void* buf = NULL; + esp_dma_mem_info_t dma_mem_info; + card->host.get_dma_info(card->host.slot, &dma_mem_info); + size_t actual_size = 0; + err = esp_dma_capable_malloc(datalen, &dma_mem_info, &buf, &actual_size); + if (err != ESP_OK) { + return err; + } + sdmmc_command_t cmd = { - .data = &buf, - .datalen = sizeof(buf), - .buflen = sizeof(buf), - .blklen = sizeof(buf), + .data = buf, + .datalen = datalen, + .buflen = actual_size, + .blklen = datalen, .flags = SCF_CMD_ADTC | SCF_RSP_R1 | SCF_CMD_READ, .opcode = SD_APP_SEND_NUM_WR_BLOCKS }; err = sdmmc_send_app_cmd(card, &cmd); if (err != ESP_OK) { + free(buf); ESP_LOGE(TAG, "%s: sdmmc_send_app_cmd returned 0x%x, failed to get number of written write blocks", __func__, err); return err; } - size_t result = __builtin_bswap32(buf); + size_t result = __builtin_bswap32(*(uint32_t*)buf); if (out_num_blocks) { *out_num_blocks = result; } + free(buf); return err; }