espressif / esp-adf

Espressif Audio Development Framework
Other
1.54k stars 677 forks source link

problem with SPI and SD card initialization / deinitialization (AUD-5435) #1207

Closed combalafra01 closed 2 months ago

combalafra01 commented 4 months ago

Environment

Problem Description

in sdcard.c, function sdcard_mount calls spi_bus_initialize and fails if the SPI bus is already initialized but sdcard_unmount does not call spi_bus_free to close the SPI bus so if when sdcard_mount is called again after sdcard_unmount, it fails and it is not possible to access the sdcard anymore (because SPI but is already initialized and sdcard_mount fails). this is a common use case when we create a first pipeline and it stops when the song is finished and we create a new one few minutes later to play an other song.

Expected Behavior

sdcard_unmount calls spi_bus_free or if impossible sdcard_mount does not fail if spi_bus_initialize returns an error

Actual Behavior

cannot call sdcard_mount after sdcard_unmount

hbler99 commented 2 months ago

You're right. sdcard_unmounted and periph_sdcard_unmount functions need to be changed as follows:

esp_err_t sdcard_unmount(const char *base_path, periph_sdcard_mode_t mode)
{
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0))
    esp_err_t ret = esp_vfs_fat_sdcard_unmount(base_path, card);
#else
    esp_err_t ret = esp_vfs_fat_sdmmc_unmount();
#endif
    if(mode == SD_MODE_SPI)
    {
        sdmmc_host_t host = SDSPI_HOST_DEFAULT();
        spi_bus_free(host.slot);
    }
    if (ret == ESP_ERR_INVALID_STATE) {
        ESP_LOGE(TAG, "File system not mounted");
    }
    return ret;
}
esp_err_t periph_sdcard_unmount(esp_periph_handle_t periph)
{
    VALIDATE_SDCARD(periph, ESP_FAIL);
    periph_sdcard_t *sdcard = esp_periph_get_data(periph);
    int ret = sdcard_unmount(sdcard->root, sdcard->sd_mode);
    // ESP_LOGW(TAG, "unmount sdcard ret = %d", ret);
    if (ret == ESP_OK) {
        ESP_LOGD(TAG, "UnMount SDCARD success");
        sdcard->is_mounted = false;
        return esp_periph_send_event(periph, SDCARD_STATUS_UNMOUNTED, NULL, 0);
    } else {
        esp_periph_send_event(periph, SDCARD_STATUS_UNMOUNT_ERROR, NULL, 0);
        ESP_LOGE(TAG, "unmount sdcard error!");
        sdcard->is_mounted = false;
        return ESP_FAIL;
    }
    return ESP_OK;
}
jason-mao commented 2 months ago

It's fixed on faabc34af57e2aec1332690c3d513ab297648543