# HG changeset patch # User Michiel Broek # Date 1625164005 -7200 # Node ID 9e00845dc1ee8c7b3a67980831125b8d8efce1a1 # Parent 03c38ad63e8cb2f40fa04481b466893fe1a58e83 SD card completly switched to the SPI driver API. diff -r 03c38ad63e8c -r 9e00845dc1ee main/task_sdcard.c --- a/main/task_sdcard.c Tue Jun 22 23:06:41 2021 +0200 +++ b/main/task_sdcard.c Thu Jul 01 20:26:45 2021 +0200 @@ -27,10 +27,11 @@ JSON_log *json_log; ///< JSON log array EventGroupHandle_t xEventGroupSDcard; ///< SD card events. +int card_handle = -1; static const char *TAG = "task_sdcard"; -static sdmmc_card_t* s_card = NULL; +static sdmmc_card_t* card = NULL; static uint8_t s_pdrv = 0; -static char * s_base_path = NULL; +//static char * s_base_path = NULL; static uint8_t pdrv = FF_DRV_NOT_USED; @@ -214,6 +215,47 @@ +static esp_err_t mount_prepare_mem(const char *base_path, BYTE *out_pdrv, char **out_dup_path, sdmmc_card_t** out_card) +{ + esp_err_t err = ESP_OK; + char* dup_path = NULL; + + // connect SDMMC driver to FATFS + BYTE pdrv = FF_DRV_NOT_USED; + if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) { + ESP_LOGD(TAG, "the maximum count of volumes is already mounted"); + return ESP_ERR_NO_MEM; + + } + + // not using ff_memalloc here, as allocation in internal RAM is preferred + card = (sdmmc_card_t*)malloc(sizeof(sdmmc_card_t)); + if (card == NULL) { + ESP_LOGD(TAG, "could not locate new sdmmc_card_t"); + err = ESP_ERR_NO_MEM; + goto cleanup; + } + + dup_path = strdup(base_path); + if (!dup_path){ + ESP_LOGD(TAG, "could not copy base_path"); + err = ESP_ERR_NO_MEM; + goto cleanup; + } + + *out_card = card; + *out_pdrv = pdrv; + *out_dup_path = dup_path; + return ESP_OK; +cleanup: + free(card); + card = NULL; + free(dup_path); + return err; +} + + + static esp_err_t my_init_sdspi_host(int slot, const void *slot_config, int *out_slot) { esp_err_t err = sdspi_host_init_device((const sdspi_device_config_t*)slot_config, out_slot); @@ -227,7 +269,7 @@ /** - * @brief This is a local modified version of the esp_vfs_fat_sdmmc_mount() function in + * @brief This is a local modified version of the esp_vfs_fat_sdspi_mount() function in * the FreeRTOS components library. It is here so we can better handle errors * for our application. * @param base_path The mount path @@ -235,49 +277,41 @@ * @param slot_config Slot configuration * @return Error condition. */ -esp_err_t my_vfs_fat_sdmmc_init(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, int *card_handle) +esp_err_t my_vfs_fat_sdspi_init(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config) { - if (s_card != NULL) { + esp_err_t err; + char* dup_path = NULL; + + if (card != NULL) { + ESP_LOGE(TAG, "card not NULL"); return ESP_ERR_INVALID_STATE; } - // connect SDMMC driver to FATFS - pdrv = FF_DRV_NOT_USED; - if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) { - ESP_LOGE(TAG, "the maximum count of volumes is already mounted"); - return ESP_ERR_NO_MEM; + err = mount_prepare_mem(base_path, &pdrv, &dup_path, &card); + if (err != ESP_OK) { + ESP_LOGE(TAG, "mount_prepare failed"); + return err; } - s_base_path = strdup(base_path); - if (!s_base_path) { - ESP_LOGE(TAG, "could not copy base_path"); - return ESP_ERR_NO_MEM; - } - esp_err_t err = ESP_OK; - s_card = malloc(sizeof(sdmmc_card_t)); - if (s_card == NULL) { - err = ESP_ERR_NO_MEM; - goto fail; - } - + //the init() function is usually empty, doesn't require any deinit to revert it err = (*host_config->init)(); if (err != ESP_OK) { - ESP_LOGE(TAG, "host init returned rc=0x%x", err); - goto fail; + ESP_LOGE(TAG, "host init returned rc=0x%x", err); + goto fail; } // configure SD host err = my_init_sdspi_host(host_config->slot, slot_config, &card_handle); if (err != ESP_OK) { - ESP_LOGE(TAG, "init_sdspi_host() rc=0x%x", err); + ESP_LOGE(TAG, "my_init_sdspi_host() rc=0x%x", err); goto fail; } return ESP_OK; fail: host_config->deinit(); - free(s_card); - s_card = NULL; + free(card); + card = NULL; return err; } @@ -292,33 +326,49 @@ * @param[out] out_card Card information * @return Error condition */ -esp_err_t my_esp_vfs_fat_sdmmc_mount(const char* base_path, - const sdmmc_host_t* host_config, - const void* slot_config, - const esp_vfs_fat_mount_config_t* mount_config, - sdmmc_card_t** out_card, - int card_handle) +esp_err_t my_esp_vfs_fat_sdspi_mount(const char* base_path, + const sdmmc_host_t* host_config_input, + const sdspi_device_config_t* slot_config, + const esp_vfs_fat_mount_config_t* mount_config, + sdmmc_card_t** out_card) { + const sdmmc_host_t* host_config = host_config_input; FATFS* fs = NULL; esp_err_t err = ESP_OK; - if (s_card == NULL) { + if (card == NULL) { + ESP_LOGE(TAG, "card not NULL"); return ESP_ERR_INVALID_STATE; } + /* + * The `slot` argument inside host_config should be replaced by the SD SPI handled returned + * above. But the input pointer is const, so create a new variable. + */ + sdmmc_host_t new_config; + if (card_handle != host_config->slot) { + new_config = *host_config_input; + host_config = &new_config; + new_config.slot = card_handle; + } + // probe and initialize card - err = sdmmc_card_init(host_config, s_card); + err = sdmmc_card_init(host_config, card); if (err != ESP_OK) { if (err != ESP_ERR_INVALID_RESPONSE) { // No card present, do not log ESP_LOGI(TAG, "sdmmc_card_init failed 0x(%x)", err); } goto fail; } + if (out_card != NULL) { - *out_card = s_card; + *out_card = card; } - ff_diskio_register_sdmmc(pdrv, s_card); + /* + * mount to vfs fat + */ + ff_diskio_register_sdmmc(pdrv, card); s_pdrv = pdrv; ESP_LOGD(TAG, "using pdrv=%i", pdrv); char drv[3] = {(char)('0' + pdrv), ':', 0}; @@ -356,9 +406,9 @@ * @brief Unmount a mounted SD card, * @return Error condition */ -esp_err_t my_esp_vfs_fat_sdmmc_unmount(void) +esp_err_t my_esp_vfs_fat_sdspi_unmount(void) { - if (s_card == NULL) { + if (card == NULL) { return ESP_ERR_INVALID_STATE; } // unmount @@ -406,7 +456,6 @@ esp_err_t ret; EventBits_t uxBits; char filename[64]; - int card_handle = -1; //uninitialized sdcard_state = malloc(sizeof(SDCARD_State)); sdcard_state->host_ok = false; @@ -442,7 +491,7 @@ /* * No errors from the sdspi_transaction driver. */ - esp_log_level_set("sdspi_transaction", ESP_LOG_NONE); +// esp_log_level_set("sdspi_transaction", ESP_LOG_NONE); /* * Options for mounting the filesystem. @@ -455,7 +504,7 @@ .allocation_unit_size = 16 * 1024 }; - ret = my_vfs_fat_sdmmc_init("/sdcard", &host, &slot_config, &card_handle); + ret = my_vfs_fat_sdspi_init("/sdcard", &host, &slot_config); if (ret == ESP_OK) { ESP_LOGI(TAG, "SPI card interface ready"); sdcard_state->host_ok = true; @@ -476,7 +525,7 @@ /* * If the card is not mounted, try it. */ - ret = my_esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card, card_handle); + ret = my_esp_vfs_fat_sdspi_mount("/sdcard", &host, &slot_config, &mount_config, &card); if (ret == ESP_OK) { ESP_LOGI(TAG, "SD card mounted on /sdcard"); sdcard_state->card_present = true; @@ -496,7 +545,7 @@ DIR* dir = opendir("/sdcard/w/log"); if (dir == NULL) { ESP_LOGI(TAG, "SD card missing, unmount"); - my_esp_vfs_fat_sdmmc_unmount(); + my_esp_vfs_fat_sdspi_unmount(); sdcard_state->card_present = false; esp_log_level_set("sdmmc_sd", ESP_LOG_NONE); } else {