SD card completly switched to the SPI driver API.

Thu, 01 Jul 2021 20:26:45 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 01 Jul 2021 20:26:45 +0200
changeset 105
9e00845dc1ee
parent 104
03c38ad63e8c
child 106
191dccfe4252

SD card completly switched to the SPI driver API.

main/task_sdcard.c file | annotate | diff | comparison | revisions
--- 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 {

mercurial