Skip to content

Commit

Permalink
SD_MMC: add ESP32-S3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
igrr committed Feb 21, 2022
1 parent f262907 commit 882484e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 26 deletions.
93 changes: 69 additions & 24 deletions libraries/SD_MMC/src/SD_MMC.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -12,29 +12,76 @@
// 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 <sys/unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#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)
{}
{
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
_pin_clk = 1;
_pin_cmd = 2;
_pin_d0 = 3;
_pin_d0 = 4;
_pin_d0 = 5;
_pin_d0 = 6;
#endif
}

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)
{
Expand All @@ -43,27 +90,25 @@ 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. Save the pins for later use in SDMMCFS::begin.
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;
#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 = {
Expand All @@ -81,7 +126,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;
Expand Down Expand Up @@ -144,4 +189,4 @@ uint64_t SDMMCFS::usedBytes()
}

SDMMCFS SD_MMC = SDMMCFS(FSImplPtr(new VFSImpl()));
#endif /* CONFIG_IDF_TARGET_ESP32 */
#endif /* SOC_SDMMC_HOST_SUPPORTED */
16 changes: 14 additions & 2 deletions libraries/SD_MMC/src/SD_MMC.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -36,8 +37,19 @@ class SDMMCFS : public FS
protected:
sdmmc_card_t* _card;

#ifdef SOC_SDMMC_USE_GPIO_MATRIX
int8_t _pin_clk;
int8_t _pin_cmd;
int8_t _pin_d0;
int8_t _pin_d1;
int8_t _pin_d2;
int8_t _pin_d3;
#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();
Expand All @@ -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_ */

0 comments on commit 882484e

Please sign in to comment.