1- // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
1+ // Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
22//
33// Licensed under the Apache License, Version 2.0 (the "License");
44// you may not use this file except in compliance with the License.
1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ #include " pins_arduino.h"
1516#include " SD_MMC.h"
16- #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) // SDMMC does not work on ESP32S2
17+ #ifdef SOC_SDMMC_HOST_SUPPORTED
1718#include " vfs_api.h"
1819
19- extern " C" {
20- #include < sys/unistd.h>
21- #include < sys/stat.h>
2220#include < dirent.h>
2321#include " esp_vfs_fat.h"
2422#include " driver/sdmmc_host.h"
2523#include " driver/sdmmc_defs.h"
2624#include " sdmmc_cmd.h"
27- }
25+ # include " soc/sdmmc_pins.h "
2826#include " ff.h"
2927
3028using namespace fs ;
31- /*
3229
33- */
3430
3531SDMMCFS::SDMMCFS (FSImplPtr impl)
36- : FS(impl), _card(NULL )
37- {}
32+ : FS(impl), _card(nullptr )
33+ {
34+ #if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC)
35+ _pin_clk = SDMMC_CLK;
36+ _pin_cmd = SDMMC_CMD;
37+ _pin_d0 = SDMMC_D0;
38+ #ifndef BOARD_HAS_1BIT_SDMMC
39+ _pin_d1 = SDMMC_D1;
40+ _pin_d2 = SDMMC_D2;
41+ _pin_d3 = SDMMC_D3;
42+ #endif // BOARD_HAS_1BIT_SDMMC
43+ #endif // defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC)
44+ }
45+
46+ bool SDMMCFS::setPins (int clk, int cmd, int d0)
47+ {
48+ return setPins (clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC);
49+ }
50+
51+ bool SDMMCFS::setPins (int clk, int cmd, int d0, int d1, int d2, int d3)
52+ {
53+ if (_card != nullptr ) {
54+ log_e (" SD_MMC.setPins must be called before SD_MMC.begin" );
55+ return false ;
56+ }
57+ #ifdef SOC_SDMMC_USE_GPIO_MATRIX
58+ // SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
59+ _pin_clk = (int8_t ) clk;
60+ _pin_cmd = (int8_t ) cmd;
61+ _pin_d0 = (int8_t ) d0;
62+ _pin_d1 = (int8_t ) d1;
63+ _pin_d2 = (int8_t ) d2;
64+ _pin_d3 = (int8_t ) d3;
65+ return true ;
66+ #elif CONFIG_IDF_TARGET_ESP32
67+ // ESP32 doesn't support SDMMC pin configuration via GPIO matrix.
68+ // Since SDMMCFS::begin hardcodes the usage of slot 1, only check if
69+ // the pins match slot 1 pins.
70+ bool pins_ok = (clk == SDMMC_SLOT1_IOMUX_PIN_NUM_CLK) &&
71+ (cmd == SDMMC_SLOT1_IOMUX_PIN_NUM_CMD) &&
72+ (d0 == SDMMC_SLOT1_IOMUX_PIN_NUM_D0) &&
73+ ((d1 == d2 == d3 == -1 ) ||
74+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D1) &&
75+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D2) &&
76+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D3));
77+ if (!pins_ok) {
78+ log_e (" SDMMCFS: specified pins are not supported by this chip." );
79+ return false ;
80+ }
81+ return true ;
82+ #else
83+ #error SoC not supported
84+ #endif
85+ }
3886
3987bool SDMMCFS::begin (const char * mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency)
4088{
@@ -43,27 +91,33 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount
4391 }
4492 // mount
4593 sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
46- sdmmc_host_t host;
94+ #ifdef SOC_SDMMC_USE_GPIO_MATRIX
95+ // SoC supports SDMMC pin configuration via GPIO matrix.
96+ // Check the pins and save them for later use in SDMMCFS::begin.
97+ if (_pin_cmd == -1 || _pin_clk == -1 || _pin_d0 == -1
98+ || (!mode1bit && (_pin_d1 == -1 || _pin_d2 == -1 || _pin_d3 == -1 ))) {
99+ log_e (" SDMMCFS: some SD pins are not set" );
100+ return false ;
101+ }
102+
103+ slot_config.clk = (gpio_num_t ) _pin_clk;
104+ slot_config.cmd = (gpio_num_t ) _pin_cmd;
105+ slot_config.d0 = (gpio_num_t ) _pin_d0;
106+ slot_config.d1 = (gpio_num_t ) _pin_d1;
107+ slot_config.d2 = (gpio_num_t ) _pin_d2;
108+ slot_config.d3 = (gpio_num_t ) _pin_d3;
109+ slot_config.width = 4 ;
110+ #endif // SOC_SDMMC_USE_GPIO_MATRIX
111+ sdmmc_host_t host = SDMMC_HOST_DEFAULT ();
47112 host.flags = SDMMC_HOST_FLAG_4BIT;
48113 host.slot = SDMMC_HOST_SLOT_1;
49114 host.max_freq_khz = sdmmc_frequency;
50- host.io_voltage = 3 .3f ;
51- host.init = &sdmmc_host_init;
52- host.set_bus_width = &sdmmc_host_set_bus_width;
53- host.get_bus_width = &sdmmc_host_get_slot_width;
54- host.set_bus_ddr_mode = &sdmmc_host_set_bus_ddr_mode;
55- host.set_card_clk = &sdmmc_host_set_card_clk;
56- host.do_transaction = &sdmmc_host_do_transaction;
57- host.deinit = &sdmmc_host_deinit;
58- host.io_int_enable = &sdmmc_host_io_int_enable;
59- host.io_int_wait = &sdmmc_host_io_int_wait;
60- host.command_timeout_ms = 0 ;
61115#ifdef BOARD_HAS_1BIT_SDMMC
62116 mode1bit = true ;
63117#endif
64118 if (mode1bit) {
65119 host.flags = SDMMC_HOST_FLAG_1BIT; // use 1-line SD mode
66- slot_config.width = 1 ;
120+ slot_config.width = 1 ;
67121 }
68122
69123 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
81135 log_w (" SD Already mounted" );
82136 return true ;
83137 } else {
84- log_e (" Failed to initialize the card (%d ). Make sure SD card lines have pull-up resistors in place." , ret);
138+ log_e (" Failed to initialize the card (0x%x ). Make sure SD card lines have pull-up resistors in place." , ret);
85139 }
86140 _card = NULL ;
87141 return false ;
@@ -144,4 +198,4 @@ uint64_t SDMMCFS::usedBytes()
144198}
145199
146200SDMMCFS SD_MMC = SDMMCFS(FSImplPtr(new VFSImpl()));
147- #endif /* CONFIG_IDF_TARGET_ESP32 */
201+ #endif /* SOC_SDMMC_HOST_SUPPORTED */
0 commit comments