From 57ed46364f7ca15bfe9b10427a5dcafe30e037b3 Mon Sep 17 00:00:00 2001 From: Vilem Zavodny Date: Fri, 11 Apr 2025 15:29:30 +0200 Subject: [PATCH] feat(bsp): New SD card API --- bsp/esp-box-3/CMakeLists.txt | 4 +- bsp/esp-box-3/esp-box-3.c | 185 ++++++++++++++++-- bsp/esp-box-3/idf_component.yml | 2 +- bsp/esp-box-3/include/bsp/esp-box-3.h | 88 ++++++++- bsp/esp32_azure_iot_kit/CMakeLists.txt | 4 +- bsp/esp32_azure_iot_kit/esp32_azure_iot_kit.c | 150 +++++++++++++- bsp/esp32_azure_iot_kit/idf_component.yml | 2 +- .../include/bsp/esp32_azure_iot_kit.h | 94 ++++++++- bsp/esp32_lyrat/CMakeLists.txt | 3 +- bsp/esp32_lyrat/esp32_lyrat.c | 151 +++++++++++++- bsp/esp32_lyrat/idf_component.yml | 2 +- bsp/esp32_lyrat/include/bsp/esp32_lyrat.h | 93 ++++++++- .../esp32_p4_function_ev_board.c | 8 + .../include/bsp/esp32_p4_function_ev_board.h | 2 +- bsp/esp32_s3_eye/CMakeLists.txt | 4 +- bsp/esp32_s3_eye/esp32_s3_eye.c | 108 ++++++++-- bsp/esp32_s3_eye/idf_component.yml | 2 +- bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h | 82 +++++++- bsp/esp32_s3_korvo_1/CMakeLists.txt | 2 +- bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c | 171 ++++++++++++++-- bsp/esp32_s3_korvo_1/idf_component.yml | 2 +- .../include/bsp/esp32_s3_korvo_1.h | 91 ++++++++- bsp/esp32_s3_korvo_2/CMakeLists.txt | 4 +- bsp/esp32_s3_korvo_2/esp32_s3_korvo_2.c | 112 +++++++++-- bsp/esp32_s3_korvo_2/idf_component.yml | 2 +- .../include/bsp/esp32_s3_korvo_2.h | 82 +++++++- bsp/esp32_s3_usb_otg/CMakeLists.txt | 4 +- bsp/esp32_s3_usb_otg/esp32_s3_usb_otg.c | 171 ++++++++++++++-- bsp/esp32_s3_usb_otg/idf_component.yml | 2 +- .../include/bsp/esp32_s3_usb_otg.h | 88 ++++++++- bsp/esp_wrover_kit/CMakeLists.txt | 4 +- bsp/esp_wrover_kit/esp_wrover_kit.c | 150 +++++++++++++- bsp/esp_wrover_kit/idf_component.yml | 2 +- .../include/bsp/esp_wrover_kit.h | 90 ++++++++- bsp/m5stack_core/CMakeLists.txt | 4 +- bsp/m5stack_core/idf_component.yml | 2 +- bsp/m5stack_core/include/bsp/m5stack_core.h | 94 ++++++++- bsp/m5stack_core/m5stack_core.c | 101 +++++++++- bsp/m5stack_core_2/CMakeLists.txt | 4 +- bsp/m5stack_core_2/idf_component.yml | 2 +- .../include/bsp/m5stack_core_2.h | 90 ++++++++- bsp/m5stack_core_2/m5stack_core_2.c | 107 ++++++++-- bsp/m5stack_core_s3/CMakeLists.txt | 4 +- bsp/m5stack_core_s3/idf_component.yml | 2 +- .../include/bsp/m5stack_core_s3.h | 88 ++++++++- bsp/m5stack_core_s3/m5stack_core_s3.c | 103 +++++++++- .../display_sensors/main/sensors_example.c | 5 +- 47 files changed, 2329 insertions(+), 238 deletions(-) diff --git a/bsp/esp-box-3/CMakeLists.txt b/bsp/esp-box-3/CMakeLists.txt index 623999b..9787a87 100644 --- a/bsp/esp-box-3/CMakeLists.txt +++ b/bsp/esp-box-3/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "esp-box-3.c" "esp-box-3_idf5.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver spiffs - PRIV_REQUIRES fatfs esp_lcd + REQUIRES driver spiffs fatfs + PRIV_REQUIRES esp_lcd ) diff --git a/bsp/esp-box-3/esp-box-3.c b/bsp/esp-box-3/esp-box-3.c index 8991557..34c112f 100644 --- a/bsp/esp-box-3/esp-box-3.c +++ b/bsp/esp-box-3/esp-box-3.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "driver/ledc.h" #include "driver/spi_master.h" @@ -60,7 +61,8 @@ static esp_lcd_panel_handle_t panel_handle = NULL; #endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) static esp_lcd_touch_handle_t tp; // LCD touch handle -sdmmc_card_t *bsp_sdcard = NULL; // Global SD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; /** * @brief I2C handle for BSP usage @@ -185,17 +187,67 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { - gpio_config_t power_gpio_config = { - .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = 1ULL << BSP_SD_POWER - }; - ESP_ERROR_CHECK(gpio_config(&power_gpio_config)); + return bsp_sdcard; +} - /* SD card power on first */ - ESP_ERROR_CHECK(gpio_set_level(BSP_SD_POWER, 0)); +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + /* SD card is connected to Slot 0 pins. Slot 0 uses IO MUX, so not specifying the pins here */ + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->cmd = BSP_SD_CMD; + config->clk = BSP_SD_CLK; + config->d0 = BSP_SD_D0; + config->d1 = BSP_SD_D1; + config->d2 = BSP_SD_D2; + config->d3 = BSP_SD_D3; + config->width = 4; + config->flags = 0; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, @@ -205,23 +257,116 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.width = 4; - slot_config.cmd = BSP_SD_CMD; - slot_config.clk = BSP_SD_CLK; - slot_config.d0 = BSP_SD_D0; - slot_config.d1 = BSP_SD_D1; - slot_config.d2 = BSP_SD_D2; - slot_config.d3 = BSP_SD_D3; + gpio_config_t power_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << BSP_SD_POWER + }; + ESP_ERROR_CHECK(gpio_config(&power_gpio_config)); - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + /* SD card power on first */ + ESP_ERROR_CHECK(gpio_set_level(BSP_SD_POWER, 0)); + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + assert(cfg); + + gpio_config_t power_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << BSP_SD_POWER + }; + ESP_ERROR_CHECK(gpio_config(&power_gpio_config)); + + /* SD card power on first */ + ESP_ERROR_CHECK(gpio_set_level(BSP_SD_POWER, 0)); + + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + gpio_reset_pin(BSP_SD_POWER); + + return ret; } esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) diff --git a/bsp/esp-box-3/idf_component.yml b/bsp/esp-box-3/idf_component.yml index f382ae9..cf27c5b 100644 --- a/bsp/esp-box-3/idf_component.yml +++ b/bsp/esp-box-3/idf_component.yml @@ -1,5 +1,5 @@ -version: "2.0.1" +version: "3.0.0" description: Board Support Package (BSP) for ESP32-S3-BOX-3 url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp-box-3 diff --git a/bsp/esp-box-3/include/bsp/esp-box-3.h b/bsp/esp-box-3/include/bsp/esp-box-3.h index ce651f6..15adb72 100644 --- a/bsp/esp-box-3/include/bsp/esp-box-3.h +++ b/bsp/esp-box-3/include/bsp/esp-box-3.h @@ -16,6 +16,8 @@ #include "driver/i2s_std.h" #include "driver/i2c_master.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "esp_codec_dev.h" #include "iot_button.h" #include "bsp/config.h" @@ -73,7 +75,7 @@ #define BSP_BUTTON_CONFIG_IO (GPIO_NUM_0) #define BSP_BUTTON_MUTE_IO (GPIO_NUM_1) -/* SD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_9) #define BSP_SD_D1 (GPIO_NUM_13) #define BSP_SD_D2 (GPIO_NUM_42) @@ -83,6 +85,12 @@ #define BSP_SD_DET (GPIO_NUM_NC) #define BSP_SD_POWER (GPIO_NUM_43) +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_9) +#define BSP_SD_SPI_CS (GPIO_NUM_12) +#define BSP_SD_SPI_MOSI (GPIO_NUM_14) +#define BSP_SD_SPI_CLK (GPIO_NUM_11) + /* PMOD */ /* * PMOD interface (peripheral module interface) is an open standard defined by Digilent Inc. @@ -284,7 +292,16 @@ esp_err_t bsp_spiffs_unmount(void); * @attention IO2 is also routed to RGB LED and push button **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI2_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -311,6 +328,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/esp32_azure_iot_kit/CMakeLists.txt b/bsp/esp32_azure_iot_kit/CMakeLists.txt index 785052d..ffbbb4b 100644 --- a/bsp/esp32_azure_iot_kit/CMakeLists.txt +++ b/bsp/esp32_azure_iot_kit/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "esp32_azure_iot_kit.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver esp_lcd - PRIV_REQUIRES fatfs spiffs + REQUIRES driver esp_lcd fatfs + PRIV_REQUIRES spiffs ) diff --git a/bsp/esp32_azure_iot_kit/esp32_azure_iot_kit.c b/bsp/esp32_azure_iot_kit/esp32_azure_iot_kit.c index 551c1ba..e094ea7 100644 --- a/bsp/esp32_azure_iot_kit/esp32_azure_iot_kit.c +++ b/bsp/esp32_azure_iot_kit/esp32_azure_iot_kit.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "esp_err.h" #include "esp_vfs_fat.h" #include "driver/ledc.h" @@ -21,7 +22,8 @@ static const char *TAG = "Azure-IoT"; static lv_display_t *disp; -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; static bool i2c_initialized = false; static const button_gpio_config_t bsp_button_config[BSP_BUTTON_NUM] = { @@ -160,9 +162,62 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { - esp_vfs_fat_sdmmc_mount_config_t mount_config = { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + /* SD card is connected to Slot 0 pins. Slot 0 uses IO MUX, so not specifying the pins here */ + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 1; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else @@ -171,17 +226,96 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.width = 1; + if (!cfg->mount) { + cfg->mount = &mount_config; + } - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + assert(cfg); + + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + return ret; } esp_err_t bsp_display_brightness_init(void) diff --git a/bsp/esp32_azure_iot_kit/idf_component.yml b/bsp/esp32_azure_iot_kit/idf_component.yml index 1106014..84e0b7c 100644 --- a/bsp/esp32_azure_iot_kit/idf_component.yml +++ b/bsp/esp32_azure_iot_kit/idf_component.yml @@ -1,4 +1,4 @@ -version: "2.1.0" +version: "3.0.0" description: Board Support Package (BSP) for ESP32-Azure-IoT-Kit url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_azure_iot_kit diff --git a/bsp/esp32_azure_iot_kit/include/bsp/esp32_azure_iot_kit.h b/bsp/esp32_azure_iot_kit/include/bsp/esp32_azure_iot_kit.h index f993f1e..5e2476a 100644 --- a/bsp/esp32_azure_iot_kit/include/bsp/esp32_azure_iot_kit.h +++ b/bsp/esp32_azure_iot_kit/include/bsp/esp32_azure_iot_kit.h @@ -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 */ @@ -14,6 +14,8 @@ #include "driver/i2c.h" #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "sdkconfig.h" #include "iot_button.h" #include "esp_lvgl_port.h" @@ -52,6 +54,18 @@ /* Buttons */ #define BSP_BUTTON_MAIN_IO (GPIO_NUM_0) +/* uSD card MMC */ +#define BSP_SD_D0 (GPIO_NUM_2) +#define BSP_SD_CMD (GPIO_NUM_15) +#define BSP_SD_CLK (GPIO_NUM_14) +#define BSP_SD_DET (GPIO_NUM_21) + +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_2) +#define BSP_SD_SPI_CS (GPIO_NUM_13) +#define BSP_SD_SPI_MOSI (GPIO_NUM_15) +#define BSP_SD_SPI_CLK (GPIO_NUM_14) + #ifdef __cplusplus extern "C" { #endif @@ -172,7 +186,16 @@ esp_err_t bsp_spiffs_unmount(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SDSPI_DEFAULT_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -199,6 +222,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/esp32_lyrat/CMakeLists.txt b/bsp/esp32_lyrat/CMakeLists.txt index 5cce953..6e764fc 100644 --- a/bsp/esp32_lyrat/CMakeLists.txt +++ b/bsp/esp32_lyrat/CMakeLists.txt @@ -9,6 +9,5 @@ idf_component_register( SRCS "esp32_lyrat.c" ${SRC_VER} INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver spiffs - PRIV_REQUIRES fatfs + REQUIRES driver spiffs fatfs ) diff --git a/bsp/esp32_lyrat/esp32_lyrat.c b/bsp/esp32_lyrat/esp32_lyrat.c index b5ea0be..8bbf80c 100644 --- a/bsp/esp32_lyrat/esp32_lyrat.c +++ b/bsp/esp32_lyrat/esp32_lyrat.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "esp_err.h" #include "esp_log.h" @@ -17,7 +18,8 @@ static const char *TAG = "LyraT"; -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; static esp_err_t bsp_touchpad_custom_deinit(button_driver_t *button_driver); static uint8_t bsp_touchpad_custom_get_key_value(button_driver_t *button_driver); @@ -161,8 +163,61 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + /* SD card is connected to Slot 0 pins. Slot 0 uses IO MUX, so not specifying the pins here */ + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 1; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, @@ -172,21 +227,97 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - const sdmmc_slot_config_t slot_config = { - .cd = SDMMC_SLOT_NO_CD, - .wp = SDMMC_SLOT_NO_WP, - .width = 1, - .flags = 0, + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 }; + assert(cfg); - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + ESP_RETURN_ON_ERROR(esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard), TAG, "SD card SPI mount failed, please check JP8. Pin 2 must be switched to ON."); + return ESP_OK; +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + return ret; } static esp_codec_dev_handle_t bsp_audio_codec_init(void) diff --git a/bsp/esp32_lyrat/idf_component.yml b/bsp/esp32_lyrat/idf_component.yml index 6c1f8fb..c9cd5ce 100644 --- a/bsp/esp32_lyrat/idf_component.yml +++ b/bsp/esp32_lyrat/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.0.0~3" +version: "2.0.0" description: Board Support Package (BSP) for ESP32-LyraT url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_lyrat diff --git a/bsp/esp32_lyrat/include/bsp/esp32_lyrat.h b/bsp/esp32_lyrat/include/bsp/esp32_lyrat.h index d088ab7..06eef8c 100644 --- a/bsp/esp32_lyrat/include/bsp/esp32_lyrat.h +++ b/bsp/esp32_lyrat/include/bsp/esp32_lyrat.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,8 @@ #include "driver/gpio.h" #include "driver/i2c.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "esp_codec_dev.h" #include "driver/touch_pad.h" #include "iot_button.h" @@ -49,14 +51,17 @@ #define BSP_I2S_DSIN (GPIO_NUM_35) // From ADC ES8388 #define BSP_POWER_AMP_IO (GPIO_NUM_21) -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_2) -#define BSP_SD_D1 (GPIO_NUM_4) -#define BSP_SD_D2 (GPIO_NUM_12) -#define BSP_SD_D3 (GPIO_NUM_13) #define BSP_SD_CMD (GPIO_NUM_15) #define BSP_SD_CLK (GPIO_NUM_14) +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_2) +#define BSP_SD_SPI_CS (GPIO_NUM_13) +#define BSP_SD_SPI_MOSI (GPIO_NUM_15) +#define BSP_SD_SPI_CLK (GPIO_NUM_14) + /* Buttons */ #define BSP_BUTTON_REC_IO (GPIO_NUM_36) #define BSP_BUTTON_MODE_IO (GPIO_NUM_39) @@ -257,7 +262,16 @@ esp_err_t bsp_spiffs_unmount(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SDSPI_DEFAULT_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -284,6 +298,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LEDs diff --git a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c index 7ae08e4..26698ef 100644 --- a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c +++ b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c @@ -204,6 +204,10 @@ esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) } cfg->host->pwr_ctrl_handle = pwr_ctrl_handle; +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); } @@ -258,6 +262,10 @@ esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) } cfg->host->pwr_ctrl_handle = pwr_ctrl_handle; +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); } diff --git a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h index 69caf3d..1e3d238 100644 --- a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h +++ b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h @@ -188,7 +188,6 @@ esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void); * \endcode **************************************************************************************************/ #define BSP_SPIFFS_MOUNT_POINT CONFIG_BSP_SPIFFS_MOUNT_POINT -#define BSP_SDSPI_HOST (SDSPI_DEFAULT_HOST) /** * @brief Mount SPIFFS to virtual file system @@ -227,6 +226,7 @@ esp_err_t bsp_spiffs_unmount(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT +#define BSP_SDSPI_HOST (SDSPI_DEFAULT_HOST) typedef struct { const esp_vfs_fat_sdmmc_mount_config_t *mount; diff --git a/bsp/esp32_s3_eye/CMakeLists.txt b/bsp/esp32_s3_eye/CMakeLists.txt index 934a548..fba5c9b 100644 --- a/bsp/esp32_s3_eye/CMakeLists.txt +++ b/bsp/esp32_s3_eye/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "esp32_s3_eye.c" "esp32_s3_eye_idf5.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES esp_driver_gpio esp_driver_sdmmc spiffs esp_driver_i2c - PRIV_REQUIRES fatfs esp_lcd esp_driver_ledc esp_driver_spi + REQUIRES esp_driver_gpio esp_driver_sdmmc spiffs esp_driver_i2c fatfs + PRIV_REQUIRES esp_lcd esp_driver_ledc esp_driver_spi ) diff --git a/bsp/esp32_s3_eye/esp32_s3_eye.c b/bsp/esp32_s3_eye/esp32_s3_eye.c index ffd94c6..89917ce 100644 --- a/bsp/esp32_s3_eye/esp32_s3_eye.c +++ b/bsp/esp32_s3_eye/esp32_s3_eye.c @@ -5,6 +5,7 @@ */ #include +#include #include "esp_vfs_fat.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" @@ -40,7 +41,7 @@ static const char *TAG = "S3-EYE"; static i2c_master_bus_handle_t i2c_handle = NULL; static bool i2c_initialized = false; static adc_oneshot_unit_handle_t bsp_adc_handle = NULL; -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler typedef enum { BSP_BUTTON_TYPE_GPIO, @@ -171,8 +172,59 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + config->clk = BSP_SD_CLK; + config->cmd = BSP_SD_CMD; + config->d0 = BSP_SD_D0; + config->d1 = GPIO_NUM_NC; + config->d2 = GPIO_NUM_NC; + config->d3 = GPIO_NUM_NC; + config->d4 = GPIO_NUM_NC; + config->d5 = GPIO_NUM_NC; + config->d6 = GPIO_NUM_NC; + config->d7 = GPIO_NUM_NC; + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 1; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, @@ -182,35 +234,49 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - const sdmmc_slot_config_t slot_config = { - .clk = BSP_SD_CLK, - .cmd = BSP_SD_CMD, - .d0 = BSP_SD_D0, - .d1 = GPIO_NUM_NC, - .d2 = GPIO_NUM_NC, - .d3 = GPIO_NUM_NC, - .d4 = GPIO_NUM_NC, - .d5 = GPIO_NUM_NC, - .d6 = GPIO_NUM_NC, - .d7 = GPIO_NUM_NC, - .cd = SDMMC_SLOT_NO_CD, - .wp = SDMMC_SLOT_NO_WP, - .width = 1, - .flags = 0, - }; + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } #if !CONFIG_FATFS_LONG_FILENAMES ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); #endif - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + return ret; } #define LCD_CMD_BITS (8) diff --git a/bsp/esp32_s3_eye/idf_component.yml b/bsp/esp32_s3_eye/idf_component.yml index d1e6083..c29cebf 100644 --- a/bsp/esp32_s3_eye/idf_component.yml +++ b/bsp/esp32_s3_eye/idf_component.yml @@ -1,4 +1,4 @@ -version: "4.0.2" +version: "5.0.0" description: Board Support Package (BSP) for ESP32-S3-EYE url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_eye diff --git a/bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h b/bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h index ca0c113..f89b53b 100644 --- a/bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h +++ b/bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h @@ -14,6 +14,8 @@ #include "sdkconfig.h" #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "esp_codec_dev.h" #include "iot_button.h" #include "bsp/config.h" @@ -76,7 +78,7 @@ #define BSP_CAMERA_D6 (GPIO_NUM_17) #define BSP_CAMERA_D7 (GPIO_NUM_16) -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_40) #define BSP_SD_CMD (GPIO_NUM_38) #define BSP_SD_CLK (GPIO_NUM_39) @@ -270,7 +272,16 @@ esp_err_t bsp_spiffs_unmount(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI3_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -297,6 +308,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/esp32_s3_korvo_1/CMakeLists.txt b/bsp/esp32_s3_korvo_1/CMakeLists.txt index a9da924..33633f5 100644 --- a/bsp/esp32_s3_korvo_1/CMakeLists.txt +++ b/bsp/esp32_s3_korvo_1/CMakeLists.txt @@ -4,7 +4,7 @@ if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_LESS "5.0") set(REQ driver spiffs fatfs) else() set(SRC_VER "esp32_s3_korvo_1_idf5.c") - set(REQ driver spiffs fatfs esp_adc) + set(REQ driver spiffs fatfs esp_adc vfs) endif() idf_component_register( diff --git a/bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c b/bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c index 84b1348..e703579 100644 --- a/bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c +++ b/bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "driver/spi_master.h" #include "driver/i2c.h" @@ -23,7 +24,8 @@ static const char *TAG = "S3-Korvo-1"; static bool i2c_initialized = false; -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; esp_err_t bsp_i2c_init(void) { @@ -311,40 +313,167 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->clk = BSP_SD_CLK; + config->cmd = BSP_SD_CMD; + config->d0 = BSP_SD_D0; + config->d1 = GPIO_NUM_NC; + config->d2 = GPIO_NUM_NC; + config->d3 = GPIO_NUM_NC; + config->d4 = GPIO_NUM_NC; + config->d5 = GPIO_NUM_NC; + config->d6 = GPIO_NUM_NC; + config->d7 = GPIO_NUM_NC; + config->width = 1; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else .format_if_mount_failed = false, #endif - .max_files = CONFIG_BSP_SD_MAX_FILES, + .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - const sdmmc_slot_config_t slot_config = { - .clk = BSP_SD_CLK, - .cmd = BSP_SD_CMD, - .d0 = BSP_SD_D0, - .d1 = GPIO_NUM_NC, - .d2 = GPIO_NUM_NC, - .d3 = GPIO_NUM_NC, - .d4 = GPIO_NUM_NC, - .d5 = GPIO_NUM_NC, - .d6 = GPIO_NUM_NC, - .d7 = GPIO_NUM_NC, - .cd = SDMMC_SLOT_NO_CD, - .wp = SDMMC_SLOT_NO_WP, - .width = 1, - .flags = 0, + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 }; + assert(cfg); - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + return ret; } diff --git a/bsp/esp32_s3_korvo_1/idf_component.yml b/bsp/esp32_s3_korvo_1/idf_component.yml index f8be097..8959e7a 100644 --- a/bsp/esp32_s3_korvo_1/idf_component.yml +++ b/bsp/esp32_s3_korvo_1/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.1.2" +version: "2.0.0" description: Board Support Package (BSP) for ESP32-S3-KORVO-1 url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_korvo_1 diff --git a/bsp/esp32_s3_korvo_1/include/bsp/esp32_s3_korvo_1.h b/bsp/esp32_s3_korvo_1/include/bsp/esp32_s3_korvo_1.h index 029b497..21fcbe9 100644 --- a/bsp/esp32_s3_korvo_1/include/bsp/esp32_s3_korvo_1.h +++ b/bsp/esp32_s3_korvo_1/include/bsp/esp32_s3_korvo_1.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,8 @@ #include "esp_codec_dev.h" #include "led_indicator.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) #include "driver/i2s.h" @@ -67,11 +69,18 @@ /* Buttons */ #define BSP_BUTTONS_IO (GPIO_NUM_8) // All 6 buttons mapped to this GPIO -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_16) +#define BSP_SD_D3 (GPIO_NUM_15) #define BSP_SD_CMD (GPIO_NUM_17) #define BSP_SD_CLK (GPIO_NUM_18) +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_16) +#define BSP_SD_SPI_CS (GPIO_NUM_15) +#define BSP_SD_SPI_MOSI (GPIO_NUM_17) +#define BSP_SD_SPI_CLK (GPIO_NUM_18) + #ifdef __cplusplus extern "C" { #endif @@ -337,7 +346,16 @@ esp_err_t bsp_spiffs_unmount(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SDSPI_DEFAULT_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -364,6 +382,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + #ifdef __cplusplus } #endif diff --git a/bsp/esp32_s3_korvo_2/CMakeLists.txt b/bsp/esp32_s3_korvo_2/CMakeLists.txt index 27680d6..c7e8e69 100644 --- a/bsp/esp32_s3_korvo_2/CMakeLists.txt +++ b/bsp/esp32_s3_korvo_2/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "esp32_s3_korvo_2.c" "esp32_s3_korvo_2_idf5.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES esp_driver_gpio esp_driver_i2s esp_driver_sdmmc esp_driver_i2c esp_adc - PRIV_REQUIRES spiffs fatfs esp_lcd esp_driver_spi esp_driver_ledc + REQUIRES esp_driver_gpio esp_driver_i2s esp_driver_sdmmc esp_driver_i2c esp_adc fatfs + PRIV_REQUIRES spiffs esp_lcd esp_driver_spi esp_driver_ledc ) diff --git a/bsp/esp32_s3_korvo_2/esp32_s3_korvo_2.c b/bsp/esp32_s3_korvo_2/esp32_s3_korvo_2.c index 72d365b..b59995f 100644 --- a/bsp/esp32_s3_korvo_2/esp32_s3_korvo_2.c +++ b/bsp/esp32_s3_korvo_2/esp32_s3_korvo_2.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "driver/ledc.h" #include "driver/spi_master.h" @@ -42,7 +43,7 @@ static const char *TAG = "S3-KORVO-2"; static i2c_master_bus_handle_t i2c_handle = NULL; static bool i2c_initialized = false; static esp_io_expander_handle_t io_expander = NULL; // IO expander tca9554 handle -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler static esp_lcd_touch_handle_t tp; // LCD touch handle static lv_indev_t *disp_indev = NULL; static adc_oneshot_unit_handle_t bsp_adc_handle = NULL; @@ -169,8 +170,59 @@ i2c_master_bus_handle_t bsp_i2c_get_handle(void) return i2c_handle; } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + config->clk = BSP_SD_CLK; + config->cmd = BSP_SD_CMD; + config->d0 = BSP_SD_D0; + config->d1 = GPIO_NUM_NC; + config->d2 = GPIO_NUM_NC; + config->d3 = GPIO_NUM_NC; + config->d4 = GPIO_NUM_NC; + config->d5 = GPIO_NUM_NC; + config->d6 = GPIO_NUM_NC; + config->d7 = GPIO_NUM_NC; + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 1; + config->flags = 0; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, @@ -180,31 +232,49 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - const sdmmc_slot_config_t slot_config = { - .clk = BSP_SD_CLK, - .cmd = BSP_SD_CMD, - .d0 = BSP_SD_D0, - .d1 = GPIO_NUM_NC, - .d2 = GPIO_NUM_NC, - .d3 = GPIO_NUM_NC, - .d4 = GPIO_NUM_NC, - .d5 = GPIO_NUM_NC, - .d6 = GPIO_NUM_NC, - .d7 = GPIO_NUM_NC, - .cd = SDMMC_SLOT_NO_CD, - .wp = SDMMC_SLOT_NO_WP, - .width = 1, - .flags = 0, - }; + if (!cfg->mount) { + cfg->mount = &mount_config; + } - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + return ret; } esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) diff --git a/bsp/esp32_s3_korvo_2/idf_component.yml b/bsp/esp32_s3_korvo_2/idf_component.yml index 45469fd..5c8a9d5 100644 --- a/bsp/esp32_s3_korvo_2/idf_component.yml +++ b/bsp/esp32_s3_korvo_2/idf_component.yml @@ -1,4 +1,4 @@ -version: "3.0.2" +version: "4.0.0" description: Board Support Package (BSP) for ESP32-S3-Korvo-2 url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_korvo_2 diff --git a/bsp/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h b/bsp/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h index 9dd7876..371d25b 100644 --- a/bsp/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h +++ b/bsp/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h @@ -10,6 +10,8 @@ #include "driver/gpio.h" #include "driver/i2s_std.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "driver/i2c_master.h" #include "esp_adc/adc_oneshot.h" #include "iot_button.h" @@ -75,7 +77,7 @@ #define BSP_CAMERA_D6 (GPIO_NUM_41) #define BSP_CAMERA_D7 (GPIO_NUM_39) -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_4) #define BSP_SD_CMD (GPIO_NUM_7) #define BSP_SD_CLK (GPIO_NUM_15) @@ -402,7 +404,16 @@ esp_io_expander_handle_t bsp_io_expander_init(void); * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI3_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -429,6 +440,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/esp32_s3_usb_otg/CMakeLists.txt b/bsp/esp32_s3_usb_otg/CMakeLists.txt index 63f8db2..b04ef6c 100644 --- a/bsp/esp32_s3_usb_otg/CMakeLists.txt +++ b/bsp/esp32_s3_usb_otg/CMakeLists.txt @@ -11,6 +11,6 @@ idf_component_register( SRCS "esp32_s3_usb_otg.c" ${SRC_VER} INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver esp_lcd - PRIV_REQUIRES fatfs usb spiffs ${REQ} + REQUIRES driver esp_lcd fatfs + PRIV_REQUIRES usb spiffs ${REQ} ) diff --git a/bsp/esp32_s3_usb_otg/esp32_s3_usb_otg.c b/bsp/esp32_s3_usb_otg/esp32_s3_usb_otg.c index fd9d985..043a051 100644 --- a/bsp/esp32_s3_usb_otg/esp32_s3_usb_otg.c +++ b/bsp/esp32_s3_usb_otg/esp32_s3_usb_otg.c @@ -5,6 +5,7 @@ */ #include +#include #include "esp_vfs_fat.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" @@ -30,7 +31,8 @@ static const char *TAG = "USB-OTG"; static TaskHandle_t usb_host_task; // USB Host Library task -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; static const button_gpio_config_t bsp_button_config[BSP_BUTTON_NUM] = { { @@ -107,10 +109,72 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->clk = BSP_SD_CLK; + config->cmd = BSP_SD_CMD; + config->d0 = BSP_SD_D0; + config->d1 = BSP_SD_D1; + config->d2 = BSP_SD_D2; + config->d3 = BSP_SD_D3; + config->d4 = GPIO_NUM_NC; + config->d5 = GPIO_NUM_NC; + config->d6 = GPIO_NUM_NC; + config->d7 = GPIO_NUM_NC; + config->width = 4; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { -#ifdef CONFIG_BSP_uSD_FORMAT_ON_MOUNT_FAIL +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else .format_if_mount_failed = false, @@ -118,31 +182,96 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - const sdmmc_slot_config_t slot_config = { - .clk = BSP_SD_CLK, - .cmd = BSP_SD_CMD, - .d0 = BSP_SD_D0, - .d1 = BSP_SD_D1, - .d2 = BSP_SD_D2, - .d3 = BSP_SD_D3, - .d4 = GPIO_NUM_NC, - .d5 = GPIO_NUM_NC, - .d6 = GPIO_NUM_NC, - .d7 = GPIO_NUM_NC, - .cd = SDMMC_SLOT_NO_CD, - .wp = SDMMC_SLOT_NO_WP, - .width = 4, - .flags = 0, + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 }; + assert(cfg); - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + return ret; } esp_err_t bsp_button_init(void) diff --git a/bsp/esp32_s3_usb_otg/idf_component.yml b/bsp/esp32_s3_usb_otg/idf_component.yml index 1f977b4..fa8ab45 100644 --- a/bsp/esp32_s3_usb_otg/idf_component.yml +++ b/bsp/esp32_s3_usb_otg/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.6.2" +version: "2.0.0" description: Board Support Package (BSP) for ESP32-S3-USB-OTG url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_usb_otg diff --git a/bsp/esp32_s3_usb_otg/include/bsp/esp32_s3_usb_otg.h b/bsp/esp32_s3_usb_otg/include/bsp/esp32_s3_usb_otg.h index 2bc2a26..88c8db2 100644 --- a/bsp/esp32_s3_usb_otg/include/bsp/esp32_s3_usb_otg.h +++ b/bsp/esp32_s3_usb_otg/include/bsp/esp32_s3_usb_otg.h @@ -14,6 +14,8 @@ #include "sdkconfig.h" #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "iot_button.h" #include "lvgl.h" #include "esp_lvgl_port.h" @@ -54,7 +56,7 @@ typedef enum bsp_led_t { #define BSP_LCD_RST (GPIO_NUM_8) #define BSP_LCD_BACKLIGHT (GPIO_NUM_9) -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_37) #define BSP_SD_D1 (GPIO_NUM_38) #define BSP_SD_D2 (GPIO_NUM_33) @@ -62,6 +64,12 @@ typedef enum bsp_led_t { #define BSP_SD_CMD (GPIO_NUM_35) #define BSP_SD_CLK (GPIO_NUM_36) +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_37) +#define BSP_SD_SPI_CS (GPIO_NUM_34) +#define BSP_SD_SPI_MOSI (GPIO_NUM_35) +#define BSP_SD_SPI_CLK (GPIO_NUM_36) + /* Buttons */ #define BSP_BUTTON_OK_IO (GPIO_NUM_0) #define BSP_BUTTON_DW_IO (GPIO_NUM_11) @@ -124,7 +132,16 @@ typedef struct { * \endcode **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI2_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -151,6 +168,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * SPIFFS diff --git a/bsp/esp_wrover_kit/CMakeLists.txt b/bsp/esp_wrover_kit/CMakeLists.txt index a04ee37..f671487 100644 --- a/bsp/esp_wrover_kit/CMakeLists.txt +++ b/bsp/esp_wrover_kit/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register(SRCS "esp_wrover_kit.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver esp_lcd - PRIV_REQUIRES fatfs spiffs) + REQUIRES driver esp_lcd fatfs + PRIV_REQUIRES spiffs) diff --git a/bsp/esp_wrover_kit/esp_wrover_kit.c b/bsp/esp_wrover_kit/esp_wrover_kit.c index ecbb872..cb44f7c 100644 --- a/bsp/esp_wrover_kit/esp_wrover_kit.c +++ b/bsp/esp_wrover_kit/esp_wrover_kit.c @@ -5,6 +5,7 @@ */ #include +#include #include "esp_vfs_fat.h" #include "esp_log.h" #include "esp_check.h" @@ -23,7 +24,8 @@ static const char *TAG = "Wrover"; -sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool spi_sd_initialized = false; static const button_gpio_config_t bsp_button_config[BSP_BUTTON_NUM] = { { @@ -84,10 +86,63 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + /* SD card is connected to Slot 0 pins. Slot 0 uses IO MUX, so not specifying the pins here */ + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 4; + config->flags = SDMMC_SLOT_FLAG_INTERNAL_PULLUP; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { -#ifdef CONFIG_BSP_uSD_FORMAT_ON_MOUNT_FAIL +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else .format_if_mount_failed = false, @@ -95,17 +150,96 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.width = 4; + if (!cfg->mount) { + cfg->mount = &mount_config; + } - return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + assert(cfg); + + ESP_LOGD(TAG, "Initialize SPI bus"); + const spi_bus_config_t buscfg = { + .sclk_io_num = BSP_SD_SPI_CLK, + .mosi_io_num = BSP_SD_SPI_MOSI, + .miso_io_num = BSP_SD_SPI_MISO, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .max_transfer_sz = 4000, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_SDSPI_HOST, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + spi_sd_initialized = true; + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + if (spi_sd_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_sd_initialized = false; + } + + return ret; } esp_err_t bsp_button_init(const bsp_button_t btn) diff --git a/bsp/esp_wrover_kit/idf_component.yml b/bsp/esp_wrover_kit/idf_component.yml index b0f4d98..9a48f63 100644 --- a/bsp/esp_wrover_kit/idf_component.yml +++ b/bsp/esp_wrover_kit/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.6.0" +version: "2.0.0" description: Board Support Package (BSP) for ESP-WROVER-KIT url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp_wrover_kit diff --git a/bsp/esp_wrover_kit/include/bsp/esp_wrover_kit.h b/bsp/esp_wrover_kit/include/bsp/esp_wrover_kit.h index 6c5518e..410700a 100644 --- a/bsp/esp_wrover_kit/include/bsp/esp_wrover_kit.h +++ b/bsp/esp_wrover_kit/include/bsp/esp_wrover_kit.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,8 @@ #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "sdkconfig.h" #include "iot_button.h" #include "bsp/config.h" @@ -64,7 +66,7 @@ typedef enum bsp_led_t { #define BSP_LCD_RST (GPIO_NUM_18) #define BSP_LCD_BACKLIGHT (GPIO_NUM_5) -/* uSD card */ +/* uSD card MMC */ #define BSP_SD_D0 (GPIO_NUM_2) #define BSP_SD_D1 (GPIO_NUM_4) #define BSP_SD_D2 (GPIO_NUM_12) @@ -73,6 +75,12 @@ typedef enum bsp_led_t { #define BSP_SD_CLK (GPIO_NUM_14) #define BSP_SD_DET (GPIO_NUM_21) +/* uSD card SPI */ +#define BSP_SD_SPI_MISO (GPIO_NUM_2) +#define BSP_SD_SPI_CS (GPIO_NUM_13) +#define BSP_SD_SPI_MOSI (GPIO_NUM_15) +#define BSP_SD_SPI_CLK (GPIO_NUM_14) + #ifdef __cplusplus extern "C" { #endif @@ -135,7 +143,16 @@ esp_err_t bsp_spiffs_unmount(void); * @attention IO2 is also routed to RGB LED and push button **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI3_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -162,6 +179,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LEDs diff --git a/bsp/m5stack_core/CMakeLists.txt b/bsp/m5stack_core/CMakeLists.txt index 8053566..0e53b9c 100644 --- a/bsp/m5stack_core/CMakeLists.txt +++ b/bsp/m5stack_core/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "m5stack_core.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver spiffs - PRIV_REQUIRES fatfs esp_lcd + REQUIRES driver spiffs fatfs + PRIV_REQUIRES esp_lcd ) diff --git a/bsp/m5stack_core/idf_component.yml b/bsp/m5stack_core/idf_component.yml index b541024..9eb063d 100644 --- a/bsp/m5stack_core/idf_component.yml +++ b/bsp/m5stack_core/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.0.0" +version: "2.0.0" description: Board Support Package (BSP) for M5Stack Core url: https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core diff --git a/bsp/m5stack_core/include/bsp/m5stack_core.h b/bsp/m5stack_core/include/bsp/m5stack_core.h index d77242a..401ef92 100644 --- a/bsp/m5stack_core/include/bsp/m5stack_core.h +++ b/bsp/m5stack_core/include/bsp/m5stack_core.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ #include "sdkconfig.h" #include "driver/gpio.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "bsp/config.h" #include "bsp/display.h" @@ -49,18 +51,18 @@ /* Display */ #define BSP_LCD_MOSI (GPIO_NUM_23) -#define BSP_LCD_MISO (GPIO_NUM_NC) +#define BSP_LCD_MISO (GPIO_NUM_19) #define BSP_LCD_PCLK (GPIO_NUM_18) #define BSP_LCD_CS (GPIO_NUM_14) #define BSP_LCD_DC (GPIO_NUM_27) #define BSP_LCD_RST (GPIO_NUM_33) #define BSP_LCD_BACKLIGHT (GPIO_NUM_32) -/* SD card */ -#define BSP_SD_MOSI (GPIO_NUM_23) -#define BSP_SD_MISO (GPIO_NUM_19) -#define BSP_SD_SCK (GPIO_NUM_18) -#define BSP_SD_CS (GPIO_NUM_4) +/* SD card SPI */ +#define BSP_SD_SPI_MOSI (GPIO_NUM_23) +#define BSP_SD_SPI_MISO (GPIO_NUM_19) +#define BSP_SD_SPI_SCK (GPIO_NUM_18) +#define BSP_SD_SPI_CS (GPIO_NUM_4) /* BUTTON */ #define BSP_BUTTON_LEFT (GPIO_NUM_39) @@ -169,7 +171,16 @@ esp_err_t bsp_spiffs_unmount(void); * @attention IO2 is also routed to RGB LED and push button **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI2_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -196,6 +207,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/m5stack_core/m5stack_core.c b/bsp/m5stack_core/m5stack_core.c index d96d8db..3f0d8c8 100644 --- a/bsp/m5stack_core/m5stack_core.c +++ b/bsp/m5stack_core/m5stack_core.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -46,6 +47,7 @@ static i2c_master_bus_handle_t i2c_handle = NULL; static bool i2c_initialized = false; static i2c_master_dev_handle_t ip5306_h = NULL; static bool spi_initialized = false; +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler esp_err_t bsp_i2c_init(void) { @@ -166,32 +168,111 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else .format_if_mount_failed = false, #endif - .max_files = 5, + .max_files = 5, .allocation_unit_size = 16 * 1024 }; - - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - host.slot = BSP_LCD_SPI_NUM; - sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); - slot_config.gpio_cs = BSP_SD_CS; - slot_config.host_id = host.slot; + assert(cfg); ESP_RETURN_ON_ERROR(bsp_spi_init((BSP_LCD_H_RES * BSP_LCD_V_RES) * sizeof(uint16_t)), TAG, ""); - return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdspi_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + //TODO: Check if LCD initialized (when LCD deinit will be covered by BSP) + if (spi_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_initialized = false; + } + + return ret; } esp_err_t bsp_speaker_init(void) diff --git a/bsp/m5stack_core_2/CMakeLists.txt b/bsp/m5stack_core_2/CMakeLists.txt index 674756f..5a6904b 100644 --- a/bsp/m5stack_core_2/CMakeLists.txt +++ b/bsp/m5stack_core_2/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "m5stack_core_2.c" "m5stack_core_2_idf5.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver spiffs - PRIV_REQUIRES fatfs esp_lcd + REQUIRES driver spiffs fatfs + PRIV_REQUIRES esp_lcd ) diff --git a/bsp/m5stack_core_2/idf_component.yml b/bsp/m5stack_core_2/idf_component.yml index 353132c..773f12d 100644 --- a/bsp/m5stack_core_2/idf_component.yml +++ b/bsp/m5stack_core_2/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.0.0" +version: "2.0.0" description: Board Support Package (BSP) for M5Stack Core2 url: https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_2 diff --git a/bsp/m5stack_core_2/include/bsp/m5stack_core_2.h b/bsp/m5stack_core_2/include/bsp/m5stack_core_2.h index ac82786..6f2ebfb 100644 --- a/bsp/m5stack_core_2/include/bsp/m5stack_core_2.h +++ b/bsp/m5stack_core_2/include/bsp/m5stack_core_2.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,8 @@ #include "driver/gpio.h" #include "driver/i2c.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "esp_codec_dev.h" #include "bsp/config.h" #include "bsp/display.h" @@ -64,10 +66,10 @@ #define BSP_LCD_TOUCH_INT (GPIO_NUM_39) /* SD card */ -#define BSP_SD_MOSI (GPIO_NUM_23) -#define BSP_SD_MISO (GPIO_NUM_38) -#define BSP_SD_SCK (GPIO_NUM_18) -#define BSP_SD_CS (GPIO_NUM_4) +#define BSP_SD_SPI_MOSI (GPIO_NUM_23) +#define BSP_SD_SPI_MISO (GPIO_NUM_38) +#define BSP_SD_SPI_SCK (GPIO_NUM_18) +#define BSP_SD_SPI_CS (GPIO_NUM_4) #ifdef __cplusplus @@ -207,7 +209,16 @@ esp_err_t bsp_spiffs_unmount(void); * @attention IO2 is also routed to RGB LED and push button **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI2_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -234,6 +245,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/m5stack_core_2/m5stack_core_2.c b/bsp/m5stack_core_2/m5stack_core_2.c index fd7f8c6..08644e5 100644 --- a/bsp/m5stack_core_2/m5stack_core_2.c +++ b/bsp/m5stack_core_2/m5stack_core_2.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "driver/spi_master.h" #include "esp_err.h" @@ -36,7 +37,7 @@ static lv_display_t *disp; static lv_indev_t *disp_indev = NULL; #endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) static esp_lcd_touch_handle_t tp; // LCD touch handle -sdmmc_card_t *bsp_sdcard = NULL; // Global SD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler static bool i2c_initialized = false; static bool spi_initialized = false; @@ -216,34 +217,116 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { - BSP_ERROR_CHECK_RETURN_ERR(bsp_feature_enable(BSP_FEATURE_SD, true)); + return bsp_sdcard; +} +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, #else .format_if_mount_failed = false, #endif - .max_files = 5, + .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - host.slot = BSP_LCD_SPI_NUM; - sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); - slot_config.gpio_cs = BSP_SD_CS; - slot_config.host_id = host.slot; + BSP_ERROR_CHECK_RETURN_ERR(bsp_feature_enable(BSP_FEATURE_SD, true)); ESP_RETURN_ON_ERROR(bsp_spi_init((BSP_LCD_H_RES * BSP_LCD_V_RES) * sizeof(uint16_t)), TAG, ""); - return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdspi_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + //TODO: Check if LCD initialized (when LCD deinit will be covered by BSP) + if (spi_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_initialized = false; + } + + return ret; } esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) diff --git a/bsp/m5stack_core_s3/CMakeLists.txt b/bsp/m5stack_core_s3/CMakeLists.txt index df8b67c..ab49848 100644 --- a/bsp/m5stack_core_s3/CMakeLists.txt +++ b/bsp/m5stack_core_s3/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "m5stack_core_s3.c" "m5stack_core_s3_idf5.c" INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES esp_driver_i2s esp_driver_gpio esp_driver_sdmmc spiffs - PRIV_REQUIRES fatfs esp_lcd esp_driver_spi esp_driver_i2c + REQUIRES esp_driver_i2s esp_driver_gpio esp_driver_sdmmc spiffs fatfs + PRIV_REQUIRES esp_lcd esp_driver_spi esp_driver_i2c ) diff --git a/bsp/m5stack_core_s3/idf_component.yml b/bsp/m5stack_core_s3/idf_component.yml index cebd330..a6e0eb8 100644 --- a/bsp/m5stack_core_s3/idf_component.yml +++ b/bsp/m5stack_core_s3/idf_component.yml @@ -1,4 +1,4 @@ -version: "2.0.1" +version: "3.0.0" description: Board Support Package (BSP) for M5Stack CoreS3 url: https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3 diff --git a/bsp/m5stack_core_s3/include/bsp/m5stack_core_s3.h b/bsp/m5stack_core_s3/include/bsp/m5stack_core_s3.h index 7e618b5..81ce6b6 100644 --- a/bsp/m5stack_core_s3/include/bsp/m5stack_core_s3.h +++ b/bsp/m5stack_core_s3/include/bsp/m5stack_core_s3.h @@ -15,6 +15,8 @@ #include "driver/gpio.h" #include "driver/i2s_std.h" #include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "esp_vfs_fat.h" #include "esp_codec_dev.h" #include "bsp/config.h" #include "bsp/display.h" @@ -79,10 +81,10 @@ #define BSP_CAMERA_D7 (GPIO_NUM_47) /* SD card */ -#define BSP_SD_MOSI (GPIO_NUM_37) -#define BSP_SD_MISO (GPIO_NUM_35) -#define BSP_SD_SCK (GPIO_NUM_36) -#define BSP_SD_CS (GPIO_NUM_4) +#define BSP_SD_SPI_MOSI (GPIO_NUM_37) +#define BSP_SD_SPI_MISO (GPIO_NUM_35) +#define BSP_SD_SPI_SCK (GPIO_NUM_36) +#define BSP_SD_SPI_CS (GPIO_NUM_4) /* USB */ #define BSP_USB_POS (GPIO_NUM_20) @@ -290,7 +292,16 @@ esp_err_t bsp_spiffs_unmount(void); * @attention IO2 is also routed to RGB LED and push button **************************************************************************************************/ #define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT -extern sdmmc_card_t *bsp_sdcard; +#define BSP_SDSPI_HOST (SPI3_HOST) + +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; /** * @brief Mount microSD card to virtual file system @@ -317,6 +328,73 @@ esp_err_t bsp_sdcard_mount(void); */ esp_err_t bsp_sdcard_unmount(void); +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + /************************************************************************************************** * * LCD interface diff --git a/bsp/m5stack_core_s3/m5stack_core_s3.c b/bsp/m5stack_core_s3/m5stack_core_s3.c index ffb7780..5d0dc85 100644 --- a/bsp/m5stack_core_s3/m5stack_core_s3.c +++ b/bsp/m5stack_core_s3/m5stack_core_s3.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "driver/gpio.h" #include "driver/i2c_master.h" #include "driver/spi_master.h" @@ -44,7 +45,7 @@ static lv_display_t *disp; static lv_indev_t *disp_indev = NULL; #endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) static esp_lcd_touch_handle_t tp; // LCD touch handle -sdmmc_card_t *bsp_sdcard = NULL; // Global SD card handler +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler /** * @brief I2C handle for BSP usage @@ -219,10 +220,60 @@ esp_err_t bsp_spiffs_unmount(void) return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); } -esp_err_t bsp_sdcard_mount(void) +sdmmc_card_t *bsp_sdcard_get_handle(void) { - BSP_ERROR_CHECK_RETURN_ERR(bsp_enable_feature(BSP_FEATURE_SD)); + return bsp_sdcard; +} +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDSPI_HOST_DEFAULT(); + host_config.slot = slot; + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + + config->gpio_cs = BSP_SD_SPI_CS; + config->gpio_cd = SDSPI_SLOT_NO_CD; + config->gpio_wp = SDSPI_SLOT_NO_WP; + config->gpio_int = GPIO_NUM_NC; + config->host_id = spi_host; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + config->gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW; +#endif +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card MMC mode is not supported by HW (Shared SPI)!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdspi_device_config_t sdslot = {0}; const esp_vfs_fat_sdmmc_mount_config_t mount_config = { #ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL .format_if_mount_failed = true, @@ -232,21 +283,53 @@ esp_err_t bsp_sdcard_mount(void) .max_files = 5, .allocation_unit_size = 16 * 1024 }; + assert(cfg); - sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - host.slot = BSP_LCD_SPI_NUM; - sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); - slot_config.gpio_cs = BSP_SD_CS; - slot_config.host_id = host.slot; + BSP_ERROR_CHECK_RETURN_ERR(bsp_enable_feature(BSP_FEATURE_SD)); ESP_RETURN_ON_ERROR(bsp_spi_init((BSP_LCD_H_RES * BSP_LCD_V_RES) * sizeof(uint16_t)), TAG, ""); - return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdspi_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdspi) { + bsp_sdcard_sdspi_get_slot(BSP_SDSPI_HOST, &sdslot); + cfg->slot.sdspi = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdspi_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdspi, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdspi_mount(&cfg); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + //TODO: Check if LCD initialized (when LCD deinit will be covered by BSP) + if (spi_initialized) { + ret |= spi_bus_free(BSP_SDSPI_HOST); + spi_initialized = false; + } + + return ret; } esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) diff --git a/examples/display_sensors/main/sensors_example.c b/examples/display_sensors/main/sensors_example.c index 4ee7ab1..1d5c205 100644 --- a/examples/display_sensors/main/sensors_example.c +++ b/examples/display_sensors/main/sensors_example.c @@ -234,9 +234,10 @@ void app_main(void) // Mount uSD card, light up WiFi LED on success if (ESP_OK == bsp_sdcard_mount()) { bsp_led_set(BSP_LED_WIFI, true); // Signal successful SD card access - sdmmc_card_print_info(stdout, bsp_sdcard); + sdmmc_card_t *sdcard = bsp_sdcard_get_handle(); + sdmmc_card_print_info(stdout, sdcard); FILE *f = fopen(BSP_SD_MOUNT_POINT "/hello.txt", "w"); - fprintf(f, "Hello %s!\n", bsp_sdcard->cid.name); + fprintf(f, "Hello %s!\n", sdcard->cid.name); fclose(f); bsp_sdcard_unmount(); }