From a45720436152e7a908791e7e4f6d2f7f9454bddb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 11 Feb 2022 23:02:53 +0100 Subject: [PATCH] SD_MMC: add ESP32-S3 support --- libraries/SD_MMC/src/SD_MMC.cpp | 104 ++++++++++++++++++++++------- libraries/SD_MMC/src/SD_MMC.h | 16 ++++- variants/esp32s3box/pins_arduino.h | 2 + 3 files changed, 95 insertions(+), 27 deletions(-) diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index ba06c261cf9..7e93cb4af13 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,29 +12,77 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "pins_arduino.h" #include "SD_MMC.h" -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) //SDMMC does not work on ESP32S2 +#ifdef SOC_SDMMC_HOST_SUPPORTED #include "vfs_api.h" -extern "C" { -#include -#include #include #include "esp_vfs_fat.h" #include "driver/sdmmc_host.h" #include "driver/sdmmc_defs.h" #include "sdmmc_cmd.h" -} +#include "soc/sdmmc_pins.h" #include "ff.h" using namespace fs; -/* -*/ SDMMCFS::SDMMCFS(FSImplPtr impl) - : FS(impl), _card(NULL) -{} + : FS(impl), _card(nullptr) +{ +#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC) + _pin_clk = SDMMC_CLK; + _pin_cmd = SDMMC_CMD; + _pin_d0 = SDMMC_D0; +#ifndef BOARD_HAS_1BIT_SDMMC + _pin_d1 = SDMMC_D1; + _pin_d2 = SDMMC_D2; + _pin_d3 = SDMMC_D3; +#endif // BOARD_HAS_1BIT_SDMMC +#endif // defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC) +} + +bool SDMMCFS::setPins(int clk, int cmd, int d0) +{ + return setPins(clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC); +} + +bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) +{ + if (_card != nullptr) { + log_e("SD_MMC.setPins must be called before SD_MMC.begin"); + return false; + } +#ifdef SOC_SDMMC_USE_GPIO_MATRIX + // SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin. + _pin_clk = (int8_t) clk; + _pin_cmd = (int8_t) cmd; + _pin_d0 = (int8_t) d0; + _pin_d1 = (int8_t) d1; + _pin_d2 = (int8_t) d2; + _pin_d3 = (int8_t) d3; + return true; +#elif CONFIG_IDF_TARGET_ESP32 + // ESP32 doesn't support SDMMC pin configuration via GPIO matrix. + // Since SDMMCFS::begin hardcodes the usage of slot 1, only check if + // the pins match slot 1 pins. + bool pins_ok = (clk == SDMMC_SLOT1_IOMUX_PIN_NUM_CLK) && + (cmd == SDMMC_SLOT1_IOMUX_PIN_NUM_CMD) && + (d0 == SDMMC_SLOT1_IOMUX_PIN_NUM_D0) && + ((d1 == d2 == d3 == -1) || + (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D1) && + (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D2) && + (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D3)); + if (!pins_ok) { + log_e("SDMMCFS: specified pins are not supported by this chip."); + return false; + } + return true; +#else +#error SoC not supported +#endif +} bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency) { @@ -43,27 +91,33 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount } //mount sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - sdmmc_host_t host; +#ifdef SOC_SDMMC_USE_GPIO_MATRIX + // SoC supports SDMMC pin configuration via GPIO matrix. + // Chech that the pins have been set either in the constructor or setPins function. + if (_pin_cmd == -1 || _pin_clk == -1 || _pin_d0 == -1 + || (!mode1bit && (_pin_d1 == -1 || _pin_d2 == -1 || _pin_d3 == -1))) { + log_e("SDMMCFS: some SD pins are not set"); + return false; + } + + slot_config.clk = (gpio_num_t) _pin_clk; + slot_config.cmd = (gpio_num_t) _pin_cmd; + slot_config.d0 = (gpio_num_t) _pin_d0; + slot_config.d1 = (gpio_num_t) _pin_d1; + slot_config.d2 = (gpio_num_t) _pin_d2; + slot_config.d3 = (gpio_num_t) _pin_d3; + slot_config.width = 4; +#endif // SOC_SDMMC_USE_GPIO_MATRIX + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); host.flags = SDMMC_HOST_FLAG_4BIT; host.slot = SDMMC_HOST_SLOT_1; host.max_freq_khz = sdmmc_frequency; - host.io_voltage = 3.3f; - host.init = &sdmmc_host_init; - host.set_bus_width = &sdmmc_host_set_bus_width; - host.get_bus_width = &sdmmc_host_get_slot_width; - host.set_bus_ddr_mode = &sdmmc_host_set_bus_ddr_mode; - host.set_card_clk = &sdmmc_host_set_card_clk; - host.do_transaction = &sdmmc_host_do_transaction; - host.deinit = &sdmmc_host_deinit; - host.io_int_enable = &sdmmc_host_io_int_enable; - host.io_int_wait = &sdmmc_host_io_int_wait; - host.command_timeout_ms = 0; #ifdef BOARD_HAS_1BIT_SDMMC mode1bit = true; #endif if(mode1bit) { host.flags = SDMMC_HOST_FLAG_1BIT; //use 1-line SD mode - slot_config.width = 1; + slot_config.width = 1; } esp_vfs_fat_sdmmc_mount_config_t mount_config = { @@ -81,7 +135,7 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount log_w("SD Already mounted"); return true; } else { - log_e("Failed to initialize the card (%d). Make sure SD card lines have pull-up resistors in place.", ret); + log_e("Failed to initialize the card (0x%x). Make sure SD card lines have pull-up resistors in place.", ret); } _card = NULL; return false; @@ -144,4 +198,4 @@ uint64_t SDMMCFS::usedBytes() } SDMMCFS SD_MMC = SDMMCFS(FSImplPtr(new VFSImpl())); -#endif /* CONFIG_IDF_TARGET_ESP32 */ +#endif /* SOC_SDMMC_HOST_SUPPORTED */ diff --git a/libraries/SD_MMC/src/SD_MMC.h b/libraries/SD_MMC/src/SD_MMC.h index e8540b32fc4..8386b23c030 100644 --- a/libraries/SD_MMC/src/SD_MMC.h +++ b/libraries/SD_MMC/src/SD_MMC.h @@ -15,7 +15,8 @@ #define _SDMMC_H_ #include "sdkconfig.h" -#ifndef CONFIG_IDF_TARGET_ESP32S2 +#include "soc/soc_caps.h" +#ifdef SOC_SDMMC_HOST_SUPPORTED #include "FS.h" #include "driver/sdmmc_types.h" @@ -36,8 +37,19 @@ class SDMMCFS : public FS protected: sdmmc_card_t* _card; +#ifdef SOC_SDMMC_USE_GPIO_MATRIX + int8_t _pin_clk = -1; + int8_t _pin_cmd = -1; + int8_t _pin_d0 = -1; + int8_t _pin_d1 = -1; + int8_t _pin_d2 = -1; + int8_t _pin_d3 = -1; +#endif + public: SDMMCFS(FSImplPtr impl); + bool setPins(int clk, int cmd, int d0); + bool setPins(int clk, int cmd, int d0, int d1, int d2, int d3); bool begin(const char * mountpoint="/sdcard", bool mode1bit=false, bool format_if_mount_failed=false, int sdmmc_frequency=BOARD_MAX_SDMMC_FREQ); void end(); sdcard_type_t cardType(); @@ -50,5 +62,5 @@ class SDMMCFS : public FS extern fs::SDMMCFS SD_MMC; -#endif /* CONFIG_IDF_TARGET_ESP32S2 */ +#endif /* SOC_SDMMC_HOST_SUPPORTED */ #endif /* _SDMMC_H_ */ diff --git a/variants/esp32s3box/pins_arduino.h b/variants/esp32s3box/pins_arduino.h index 687468251f9..054fe9689d1 100644 --- a/variants/esp32s3box/pins_arduino.h +++ b/variants/esp32s3box/pins_arduino.h @@ -62,12 +62,14 @@ static const uint8_t T14 = 14; #define I2S_SDIN 16 #define I2S_DOUT 15 +#define BOARD_HAS_SDMMC #define SDMMC_CLK 13 #define SDMMC_CMD 11 #define SDMMC_D0 14 #define SDMMC_D1 12 #define SDMMC_D2 10 #define SDMMC_D3 9 +#define BOARD_MAX_SDMMC_FREQ SDMMC_FREQ_DEFAULT #define PA_PIN 46 //Audio Amp Power #define MUTE_PIN 1 //MUTE Button