From e8ad9b05aa04e50fad470f55991e0932495d683c Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 15 Jan 2025 16:16:10 +0800 Subject: [PATCH] refactor(sd): replace esp_dma_ with heap_caps_ --- .../include/driver/sdmmc_default_configs.h | 3 +- .../include/driver/sdmmc_host.h | 19 +++++- components/esp_driver_sdmmc/src/sdmmc_host.c | 36 ++++++++++- .../esp_driver_sdmmc/src/sdmmc_transaction.c | 11 ++-- .../common_test_flows/sdmmc_test_rw_common.c | 19 ++---- components/esp_driver_sdspi/CMakeLists.txt | 2 +- .../include/driver/sdspi_host.h | 22 ++++++- components/esp_driver_sdspi/src/sdspi_host.c | 18 +++++- .../sdmmc/include/esp_private/sdmmc_common.h | 7 ++- components/sdmmc/include/sd_protocol_types.h | 1 + components/sdmmc/sdmmc_cmd.c | 63 +++++++++---------- components/sdmmc/sdmmc_common.c | 22 +++++-- components/sdmmc/sdmmc_init.c | 3 + components/sdmmc/sdmmc_io.c | 15 ++--- components/sdmmc/sdmmc_mmc.c | 24 ++++--- components/sdmmc/sdmmc_sd.c | 24 ++++--- 16 files changed, 186 insertions(+), 103 deletions(-) diff --git a/components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h b/components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h index 5b0bc07f0f..1112bcd1bc 100644 --- a/components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h +++ b/components/esp_driver_sdmmc/include/driver/sdmmc_default_configs.h @@ -49,7 +49,8 @@ extern "C" { .set_input_delay = &sdmmc_host_set_input_delay, \ .dma_aligned_buffer = NULL, \ .pwr_ctrl_handle = NULL, \ - .get_dma_info = &sdmmc_host_get_dma_info, \ + .get_dma_info = NULL, \ + .check_buffer_alignment = &sdmmc_host_check_buffer_alignment, \ .is_slot_set_to_uhs1 = &sdmmc_host_is_slot_set_to_uhs1, \ } diff --git a/components/esp_driver_sdmmc/include/driver/sdmmc_host.h b/components/esp_driver_sdmmc/include/driver/sdmmc_host.h index 037dbe83cf..d6d3f856ac 100644 --- a/components/esp_driver_sdmmc/include/driver/sdmmc_host.h +++ b/components/esp_driver_sdmmc/include/driver/sdmmc_host.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ #include #include +#include #include "esp_err.h" #include "driver/sdmmc_types.h" #include "driver/sdmmc_default_configs.h" @@ -276,13 +277,27 @@ esp_err_t sdmmc_host_set_input_delay(int slot, sdmmc_delay_phase_t delay_phase); /** * @brief Get the DMA memory information for the host driver * + * @deprecated This API is deprecated + * * @param[in] slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) * @param[out] dma_mem_info DMA memory information structure * @return * - ESP_OK: ON success. * - ESP_ERR_INVALID_ARG: Invalid argument. */ -esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info); +esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) __attribute__((deprecated("This API is deprecated"))); + +/** + * @brief Check if the buffer meets the alignment requirements + * + * @param[in] slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param[in] buf buffer pointer + * @param[in] size buffer size + * + * @return + * True for aligned buffer, false for not aligned buffer + */ +bool sdmmc_host_check_buffer_alignment(int slot, const void *buf, size_t size); /** * @brief Check if the slot is set to uhs1 or not diff --git a/components/esp_driver_sdmmc/src/sdmmc_host.c b/components/esp_driver_sdmmc/src/sdmmc_host.c index 92099c6104..ef10e7f2ef 100644 --- a/components/esp_driver_sdmmc/src/sdmmc_host.c +++ b/components/esp_driver_sdmmc/src/sdmmc_host.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,9 +20,11 @@ #include "driver/sdmmc_host.h" #include "esp_private/esp_clk_tree_common.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_cache_private.h" #include "sdmmc_internal.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include "esp_memory_utils.h" #include "esp_clk_tree.h" #include "soc/sdmmc_periph.h" #include "soc/soc_caps.h" @@ -1161,6 +1163,38 @@ esp_err_t sdmmc_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) return ESP_OK; } +bool sdmmc_host_check_buffer_alignment(int slot, const void *buf, size_t size) +{ + //for future-proof + (void)slot; + + if (!buf || !size) { + return ESP_FAIL; + } + + esp_err_t ret = ESP_FAIL; + int cache_flags = 0; + size_t cache_alignment_bytes = 0; + if (esp_ptr_external_ram(buf)) { + cache_flags |= MALLOC_CAP_SPIRAM; + } + ret = esp_cache_get_alignment(cache_flags, &cache_alignment_bytes); + assert(ret == ESP_OK); + + bool is_aligned = false; + size_t alignment = 0; + + if (cache_alignment_bytes != 0) { + alignment = cache_alignment_bytes; + } else { + alignment = 4; + } + + is_aligned = ((intptr_t)buf % alignment == 0) && (size % alignment == 0); + + return is_aligned; +} + esp_err_t sdmmc_host_get_state(sdmmc_host_state_t* state) { if (state == NULL) { diff --git a/components/esp_driver_sdmmc/src/sdmmc_transaction.c b/components/esp_driver_sdmmc/src/sdmmc_transaction.c index 55cf55a402..c9b5fd80e6 100644 --- a/components/esp_driver_sdmmc/src/sdmmc_transaction.c +++ b/components/esp_driver_sdmmc/src/sdmmc_transaction.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -147,12 +147,9 @@ esp_err_t sdmmc_host_do_transaction(int slot, sdmmc_command_t* cmdinfo) ret = ESP_ERR_INVALID_SIZE; goto out; } - esp_dma_mem_info_t dma_mem_info; - sdmmc_host_get_dma_info(slot, &dma_mem_info); -#ifdef SOC_SDMMC_PSRAM_DMA_CAPABLE - dma_mem_info.extra_heap_caps |= MALLOC_CAP_SPIRAM; -#endif - if (!esp_dma_is_buffer_alignment_satisfied(cmdinfo->data, cmdinfo->buflen, dma_mem_info)) { + + bool is_aligned = sdmmc_host_check_buffer_alignment(slot, cmdinfo->data, cmdinfo->buflen); + if (!is_aligned) { ESP_LOGE(TAG, "%s: buffer %p can not be used for DMA", __func__, cmdinfo->data); ret = ESP_ERR_INVALID_ARG; goto out; diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c index b883e00435..ca337fa8a9 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +9,6 @@ #include #include #include -#include "esp_dma_utils.h" #include "esp_heap_caps.h" #include "test_utils.h" #include "sdkconfig.h" @@ -53,13 +52,9 @@ static void do_single_rw_perf_test(sdmmc_card_t* card, size_t start_block, const char* alloc_str = (extra_alloc_caps & MALLOC_CAP_SPIRAM) ? "spiram" : " sram "; printf(" %8d | %3d | %d | %s | %4.1f ", start_block, block_count, alignment, alloc_str, total_size / 1024.0f); - size_t actual_size = 0; uint32_t *buffer = NULL; - esp_dma_mem_info_t dma_mem_info = { - .extra_heap_caps = extra_alloc_caps, - .dma_alignment_bytes = 64, - }; - TEST_ESP_OK(esp_dma_capable_malloc(total_size + 4, &dma_mem_info, (void**) &buffer, &actual_size)); + buffer = heap_caps_malloc(total_size + 4, MALLOC_CAP_DMA); + TEST_ASSERT(buffer); size_t offset = alignment % 4; uint8_t* c_buffer = (uint8_t*) buffer + offset; @@ -107,12 +102,10 @@ void sdmmc_test_rw_unaligned_buffer(sdmmc_card_t* card) const size_t block_count = buffer_size / 512; const size_t extra = 4; const size_t total_size = buffer_size + extra; - size_t actual_size = 0; uint8_t *buffer = NULL; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = 64, - }; - TEST_ESP_OK(esp_dma_capable_malloc(total_size + 4, &dma_mem_info, (void**) &buffer, &actual_size)); + + buffer = heap_caps_malloc(total_size + 4, MALLOC_CAP_DMA); + TEST_ASSERT(buffer); // Check read behavior: do aligned write, then unaligned read const uint32_t seed = 0x89abcdef; diff --git a/components/esp_driver_sdspi/CMakeLists.txt b/components/esp_driver_sdspi/CMakeLists.txt index b9af00622a..73bb453bc7 100644 --- a/components/esp_driver_sdspi/CMakeLists.txt +++ b/components/esp_driver_sdspi/CMakeLists.txt @@ -15,7 +15,7 @@ if(${target} STREQUAL "linux") set(priv_requires esp_timer) else() set(requires sdmmc esp_driver_spi esp_driver_gpio) - set(priv_requires esp_timer) + set(priv_requires esp_timer esp_mm) endif() idf_component_register(SRCS ${srcs} diff --git a/components/esp_driver_sdspi/include/driver/sdspi_host.h b/components/esp_driver_sdspi/include/driver/sdspi_host.h index e6ead840f8..73410bdb02 100644 --- a/components/esp_driver_sdspi/include/driver/sdspi_host.h +++ b/components/esp_driver_sdspi/include/driver/sdspi_host.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include +#include #include "esp_err.h" #include "sd_protocol_types.h" #include "driver/gpio.h" @@ -61,7 +62,8 @@ typedef int sdspi_dev_handle_t; .set_input_delay = NULL, \ .dma_aligned_buffer = NULL, \ .pwr_ctrl_handle = NULL, \ - .get_dma_info = &sdspi_host_get_dma_info, \ + .get_dma_info = NULL, \ + .check_buffer_alignment = sdspi_host_check_buffer_alignment, \ .is_slot_set_to_uhs1 = NULL, \ } @@ -223,13 +225,27 @@ esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_t /** * @brief Get the DMA memory information for the host driver * + * @deprecated This API is deprecated + * * @param[in] slot Not used * @param[out] dma_mem_info DMA memory information structure * @return * - ESP_OK: ON success. * - ESP_ERR_INVALID_ARG: Invalid argument. */ -esp_err_t sdspi_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info); +esp_err_t sdspi_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) __attribute__((deprecated("This API is deprecated"))); + +/** + * @brief Check if the buffer meets the alignment requirements + * + * @param[in] slot slot number (SDMMC_HOST_SLOT_0 or SDMMC_HOST_SLOT_1) + * @param[in] buf buffer pointer + * @param[in] size buffer size + * + * @return + * True for aligned buffer, false for not aligned buffer + */ +bool sdspi_host_check_buffer_alignment(int slot, const void *buf, size_t size); #ifdef __cplusplus } diff --git a/components/esp_driver_sdspi/src/sdspi_host.c b/components/esp_driver_sdspi/src/sdspi_host.c index f532dd4909..90f4df8042 100644 --- a/components/esp_driver_sdspi/src/sdspi_host.c +++ b/components/esp_driver_sdspi/src/sdspi_host.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +21,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "soc/soc_memory_layout.h" +#include "esp_private/esp_cache_private.h" /// Max number of transactions in flight (used in start_command_write_blocks) #define SDSPI_TRANSACTION_COUNT 4 @@ -1009,3 +1010,18 @@ esp_err_t sdspi_host_get_dma_info(int slot, esp_dma_mem_info_t *dma_mem_info) dma_mem_info->dma_alignment_bytes = 4; return ESP_OK; } + +bool sdspi_host_check_buffer_alignment(int slot, const void *buf, size_t size) +{ + //for future-proof + (void)slot; + + if (!buf || !size) { + return ESP_FAIL; + } + + //spi master driver will deal with the buffer alignment + bool is_aligned = ((intptr_t)buf % 4 == 0) && (size % 4 == 0); + + return is_aligned; +} diff --git a/components/sdmmc/include/esp_private/sdmmc_common.h b/components/sdmmc/include/esp_private/sdmmc_common.h index 07096e6d6c..ccf599ef4e 100644 --- a/components/sdmmc/include/esp_private/sdmmc_common.h +++ b/components/sdmmc/include/esp_private/sdmmc_common.h @@ -28,7 +28,6 @@ #include "sys/param.h" #include "soc/soc_memory_layout.h" #include "soc/soc_caps.h" -#include "esp_dma_utils.h" #ifdef __cplusplus extern "C" { @@ -187,6 +186,12 @@ esp_err_t sdmmc_wait_for_idle(sdmmc_card_t* card, uint32_t status); #define SDMMC_IO_BLOCK_SIZE 512 esp_err_t sdmmc_allocate_aligned_buf(sdmmc_card_t* card); +/** + * For newly added host driver function pointers, + * use this function to check if they are correctly initialised. + */ +esp_err_t sdmmc_check_host_function_ptr_integrity(sdmmc_card_t *card); + #ifdef __cplusplus } #endif diff --git a/components/sdmmc/include/sd_protocol_types.h b/components/sdmmc/include/sd_protocol_types.h index 70cdf76d12..66a5bfe499 100644 --- a/components/sdmmc/include/sd_protocol_types.h +++ b/components/sdmmc/include/sd_protocol_types.h @@ -242,6 +242,7 @@ typedef struct { void* dma_aligned_buffer; /*!< Leave it NULL. Reserved for cache aligned buffers for SDIO mode */ sd_pwr_ctrl_handle_t pwr_ctrl_handle; /*!< Power control handle */ esp_err_t (*get_dma_info)(int slot, esp_dma_mem_info_t *dma_mem_info); /*!< host function to dma memory information*/ + bool (*check_buffer_alignment)(int slot, const void *buf, size_t size); /*!< Check if buffer meets alignment requirements */ esp_err_t (*is_slot_set_to_uhs1)(int slot, bool *is_uhs1); /*!< host slot is set to uhs1 or not*/ } sdmmc_host_t; diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 71f23ec756..a928dee6d2 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -340,14 +340,13 @@ esp_err_t sdmmc_send_cmd_send_scr(sdmmc_card_t* card, sdmmc_scr_t *out_scr) { size_t datalen = 8; esp_err_t err = ESP_FAIL; - void *buf = NULL; - size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - err = esp_dma_capable_malloc(datalen, &dma_mem_info, &buf, &actual_size); - if (err != ESP_OK) { - return err; + + void *buf = heap_caps_malloc(datalen, MALLOC_CAP_DMA); + if (!buf) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + size_t actual_size = heap_caps_get_allocated_size(buf); sdmmc_command_t cmd = { .data = buf, @@ -412,14 +411,13 @@ esp_err_t sdmmc_send_cmd_num_of_written_blocks(sdmmc_card_t* card, size_t* out_n { size_t datalen = sizeof(uint32_t); esp_err_t err = ESP_OK; - 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; + + void *buf = heap_caps_malloc(datalen, MALLOC_CAP_DMA); + if (!buf) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + size_t actual_size = heap_caps_get_allocated_size(buf); sdmmc_command_t cmd = { .data = buf, @@ -454,12 +452,9 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, esp_err_t err = ESP_OK; size_t block_size = card->csd.sector_size; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); -#ifdef SOC_SDMMC_PSRAM_DMA_CAPABLE - dma_mem_info.extra_heap_caps |= MALLOC_CAP_SPIRAM; -#endif - if (esp_dma_is_buffer_alignment_satisfied(src, block_size * block_count, dma_mem_info) + bool is_aligned = card->host.check_buffer_alignment(card->host.slot, src, block_size * block_count); + + if (is_aligned #if !SOC_SDMMC_PSRAM_DMA_CAPABLE && !esp_ptr_external_ram(src) #endif @@ -471,13 +466,14 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, // DMA-capable buffer. void *tmp_buf = NULL; size_t actual_size = 0; - // Clear the SPIRAM flag. We don't want to force the allocation into SPIRAM, the allocator + // We don't want to force the allocation into SPIRAM, the allocator // will decide based on the buffer size and memory availability. - dma_mem_info.extra_heap_caps &= ~MALLOC_CAP_SPIRAM; - err = esp_dma_capable_malloc(block_size, &dma_mem_info, &tmp_buf, &actual_size); - if (err != ESP_OK) { - return err; + tmp_buf = heap_caps_malloc(block_size, MALLOC_CAP_DMA); + if (!tmp_buf) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + actual_size = heap_caps_get_allocated_size(tmp_buf); const uint8_t* cur_src = (const uint8_t*) src; for (size_t i = 0; i < block_count; ++i) { @@ -594,9 +590,9 @@ esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst, esp_err_t err = ESP_OK; size_t block_size = card->csd.sector_size; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - if (esp_dma_is_buffer_alignment_satisfied(dst, block_size * block_count, dma_mem_info) + bool is_aligned = card->host.check_buffer_alignment(card->host.slot, dst, block_size * block_count); + + if (is_aligned #if !SOC_SDMMC_PSRAM_DMA_CAPABLE && !esp_ptr_external_ram(dst) #endif @@ -608,10 +604,13 @@ esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst, // DMA-capable buffer. void *tmp_buf = NULL; size_t actual_size = 0; - err = esp_dma_capable_malloc(block_size, &dma_mem_info, &tmp_buf, &actual_size); - if (err != ESP_OK) { - return err; + tmp_buf = heap_caps_malloc(block_size, MALLOC_CAP_DMA); + if (!tmp_buf) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + actual_size = heap_caps_get_allocated_size(tmp_buf); + uint8_t* cur_dst = (uint8_t*) dst; for (size_t i = 0; i < block_count; ++i) { err = sdmmc_read_sectors_dma(card, tmp_buf, start_block + i, 1, actual_size); diff --git a/components/sdmmc/sdmmc_common.c b/components/sdmmc/sdmmc_common.c index 169a95dd9b..f2e6a99388 100644 --- a/components/sdmmc/sdmmc_common.c +++ b/components/sdmmc/sdmmc_common.c @@ -395,20 +395,30 @@ esp_err_t sdmmc_allocate_aligned_buf(sdmmc_card_t* card) { if (card->host.flags & SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF) { void* buf = NULL; - size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - esp_err_t ret = esp_dma_capable_malloc(SDMMC_IO_BLOCK_SIZE, &dma_mem_info, &buf, &actual_size); - if (ret != ESP_OK) { - return ret; + size_t actual_size = 0; + buf = heap_caps_malloc(SDMMC_IO_BLOCK_SIZE, MALLOC_CAP_DMA); + if (!buf) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + actual_size = heap_caps_get_allocated_size(buf); + assert(actual_size == SDMMC_IO_BLOCK_SIZE); card->host.dma_aligned_buffer = buf; } return ESP_OK; } +esp_err_t sdmmc_check_host_function_ptr_integrity(sdmmc_card_t *card) +{ + if (!card->host.check_buffer_alignment) { + ESP_LOGE(TAG, "%s: host drv check_buffer_alignment not initialised, err=0x%x", __func__, ESP_ERR_INVALID_ARG); + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + uint32_t sdmmc_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_t erase_size_kb) { if (card->is_mmc) { diff --git a/components/sdmmc/sdmmc_init.c b/components/sdmmc/sdmmc_init.c index 3e62209d36..6e7bf863f8 100644 --- a/components/sdmmc/sdmmc_init.c +++ b/components/sdmmc/sdmmc_init.c @@ -68,6 +68,9 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card) /* Check if host flags are compatible with slot configuration. */ SDMMC_INIT_STEP(!is_spi, sdmmc_fix_host_flags); + /* Check if host function pointers are correctly initialised */ + SDMMC_INIT_STEP(always, sdmmc_check_host_function_ptr_integrity); + /* Reset SDIO (CMD52, RES) before re-initializing IO (CMD5). */ SDMMC_INIT_STEP(io_supported, sdmmc_io_reset); diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 64492f2da3..953a7ee0c4 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -319,9 +319,8 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func, .blklen = SDMMC_IO_BLOCK_SIZE /* TODO: read max block size from CIS */ }; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - if (unlikely(datalen > 0 && !esp_dma_is_buffer_alignment_satisfied(datap, buflen, dma_mem_info))) { + bool is_aligned = card->host.check_buffer_alignment(card->host.slot, datap, buflen); + if (unlikely(datalen > 0 && !is_aligned)) { if (datalen > SDMMC_IO_BLOCK_SIZE || card->host.dma_aligned_buffer == NULL) { // User gives unaligned buffer while `SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF` not set. return ESP_ERR_INVALID_ARG; @@ -463,9 +462,8 @@ esp_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function, addr &= ~SDMMC_IO_FIXED_ADDR; } - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - if (unlikely(!esp_dma_is_buffer_alignment_satisfied(dst, size, dma_mem_info))) { + bool is_aligned = card->host.check_buffer_alignment(card->host.slot, dst, size); + if (unlikely(!is_aligned)) { return ESP_ERR_INVALID_ARG; } return sdmmc_io_rw_extended(card, function, addr, arg, dst, size); @@ -481,9 +479,8 @@ esp_err_t sdmmc_io_write_blocks(sdmmc_card_t* card, uint32_t function, addr &= ~SDMMC_IO_FIXED_ADDR; } - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - if (unlikely(!esp_dma_is_buffer_alignment_satisfied(src, size, dma_mem_info))) { + bool is_aligned = card->host.check_buffer_alignment(card->host.slot, src, size); + if (unlikely(!is_aligned)) { return ESP_ERR_INVALID_ARG; } return sdmmc_io_rw_extended(card, function, addr, arg, (void*) src, size); diff --git a/components/sdmmc/sdmmc_mmc.c b/components/sdmmc/sdmmc_mmc.c index a4fed8a4c9..24bbe9ef9f 100644 --- a/components/sdmmc/sdmmc_mmc.c +++ b/components/sdmmc/sdmmc_mmc.c @@ -28,14 +28,12 @@ esp_err_t sdmmc_init_mmc_read_ext_csd(sdmmc_card_t* card) esp_err_t err = ESP_OK; uint8_t* ext_csd = NULL; size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - err = esp_dma_capable_malloc(EXT_CSD_MMC_SIZE, &dma_mem_info, (void *)&ext_csd, &actual_size); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: could not allocate ext_csd", __func__); - return err; + ext_csd = heap_caps_malloc(EXT_CSD_MMC_SIZE, MALLOC_CAP_DMA); + if (!ext_csd) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } - + actual_size = heap_caps_get_allocated_size(ext_csd); uint32_t sectors = 0; ESP_LOGD(TAG, "MMC version: %d", card->csd.mmc_ver); @@ -257,13 +255,13 @@ esp_err_t sdmmc_init_mmc_check_ext_csd(sdmmc_card_t* card) /* ensure EXT_CSD buffer is available before starting any SD-card operation */ uint8_t* ext_csd = NULL; size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - esp_err_t err = esp_dma_capable_malloc(EXT_CSD_MMC_SIZE, &dma_mem_info, (void *)&ext_csd, &actual_size); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: could not allocate ext_csd", __func__); - return err; + esp_err_t err = ESP_FAIL; + ext_csd = heap_caps_malloc(EXT_CSD_MMC_SIZE, MALLOC_CAP_DMA); + if (!ext_csd) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + actual_size = heap_caps_get_allocated_size(ext_csd); /* ensure card is in transfer state before read ext_csd */ uint32_t status; diff --git a/components/sdmmc/sdmmc_sd.c b/components/sdmmc/sdmmc_sd.c index 45b13beb6e..b1bf764015 100644 --- a/components/sdmmc/sdmmc_sd.c +++ b/components/sdmmc/sdmmc_sd.c @@ -92,13 +92,13 @@ esp_err_t sdmmc_init_sd_ssr(sdmmc_card_t* card) */ uint32_t* sd_ssr = NULL; size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - err = esp_dma_capable_calloc(1, SD_SSR_SIZE, &dma_mem_info, (void *)&sd_ssr, &actual_size); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: could not allocate sd_ssr", __func__); - return err; + + sd_ssr = heap_caps_calloc(1, SD_SSR_SIZE, MALLOC_CAP_DMA); + if (!sd_ssr) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } + actual_size = heap_caps_get_allocated_size(sd_ssr); sdmmc_command_t cmd = { .data = sd_ssr, @@ -240,14 +240,12 @@ esp_err_t sdmmc_enter_higher_speed_mode(sdmmc_card_t* card) return ESP_ERR_NOT_SUPPORTED; } - size_t actual_size = 0; sdmmc_switch_func_rsp_t *response = NULL; - esp_dma_mem_info_t dma_mem_info; - card->host.get_dma_info(card->host.slot, &dma_mem_info); - esp_err_t err = esp_dma_capable_malloc(sizeof(*response), &dma_mem_info, (void *)&response, &actual_size); - assert(actual_size == sizeof(*response)); - if (err != ESP_OK) { - return err; + esp_err_t err = ESP_FAIL; + response = heap_caps_malloc(sizeof(*response), MALLOC_CAP_DMA); + if (!response) { + ESP_LOGE(TAG, "%s: not enough mem, err=0x%x", __func__, ESP_ERR_NO_MEM); + return ESP_ERR_NO_MEM; } err = sdmmc_send_cmd_switch_func(card, 0, SD_ACCESS_MODE, 0, response);