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)
3632 : FS(impl), _card(NULL )
37- {}
33+ {
34+ #ifdef SOC_SDMMC_USE_GPIO_MATRIX
35+ _pin_clk = 1 ;
36+ _pin_cmd = 2 ;
37+ _pin_d0 = 3 ;
38+ _pin_d0 = 4 ;
39+ _pin_d0 = 5 ;
40+ _pin_d0 = 6 ;
41+ #endif
42+ }
43+
44+ bool SDMMCFS::setPins (int clk, int cmd, int d0)
45+ {
46+ return setPins (clk, cmd, d0, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC);
47+ }
48+
49+ bool SDMMCFS::setPins (int clk, int cmd, int d0, int d1, int d2, int d3)
50+ {
51+ if (_card != nullptr ) {
52+ log_e (" SD_MMC.setPins must be called before SD_MMC.begin" );
53+ return false ;
54+ }
55+ #ifdef SOC_SDMMC_USE_GPIO_MATRIX
56+ // SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
57+ _pin_clk = (int8_t ) clk;
58+ _pin_cmd = (int8_t ) cmd;
59+ _pin_d0 = (int8_t ) d0;
60+ _pin_d1 = (int8_t ) d1;
61+ _pin_d2 = (int8_t ) d2;
62+ _pin_d3 = (int8_t ) d3;
63+ return true ;
64+ #elif CONFIG_IDF_TARGET_ESP32
65+ // ESP32 doesn't support SDMMC pin configuration via GPIO matrix.
66+ // Since SDMMCFS::begin hardcodes the usage of slot 1, only check if
67+ // the pins match slot 1 pins.
68+ bool pins_ok = (clk == SDMMC_SLOT1_IOMUX_PIN_NUM_CLK) &&
69+ (cmd == SDMMC_SLOT1_IOMUX_PIN_NUM_CMD) &&
70+ (d0 == SDMMC_SLOT1_IOMUX_PIN_NUM_D0) &&
71+ ((d1 == d2 == d3 == -1 ) ||
72+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D1) &&
73+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D2) &&
74+ (d1 == SDMMC_SLOT1_IOMUX_PIN_NUM_D3));
75+ if (!pins_ok) {
76+ log_e (" SDMMCFS: specified pins are not supported by this chip." );
77+ return false ;
78+ }
79+ return true ;
80+ #else
81+ #error SoC not supported
82+ #endif
83+ }
84+
3885
3986bool SDMMCFS::begin (const char * mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency)
4087{
@@ -43,27 +90,25 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount
4390 }
4491 // mount
4592 sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT ();
46- sdmmc_host_t host;
93+ #ifdef SOC_SDMMC_USE_GPIO_MATRIX
94+ // SoC supports SDMMC pin configuration via GPIO matrix. Save the pins for later use in SDMMCFS::begin.
95+ slot_config.clk = (gpio_num_t ) _pin_clk;
96+ slot_config.cmd = (gpio_num_t ) _pin_cmd;
97+ slot_config.d0 = (gpio_num_t ) _pin_d0;
98+ slot_config.d1 = (gpio_num_t ) _pin_d1;
99+ slot_config.d2 = (gpio_num_t ) _pin_d2;
100+ slot_config.d3 = (gpio_num_t ) _pin_d3;
101+ #endif // SOC_SDMMC_USE_GPIO_MATRIX
102+ sdmmc_host_t host = SDMMC_HOST_DEFAULT ();
47103 host.flags = SDMMC_HOST_FLAG_4BIT;
48104 host.slot = SDMMC_HOST_SLOT_1;
49105 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 ;
61106#ifdef BOARD_HAS_1BIT_SDMMC
62107 mode1bit = true ;
63108#endif
64109 if (mode1bit) {
65110 host.flags = SDMMC_HOST_FLAG_1BIT; // use 1-line SD mode
66- slot_config.width = 1 ;
111+ slot_config.width = 1 ;
67112 }
68113
69114 esp_vfs_fat_sdmmc_mount_config_t mount_config = {
@@ -81,7 +126,7 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount
81126 log_w (" SD Already mounted" );
82127 return true ;
83128 } else {
84- log_e (" Failed to initialize the card (%d ). Make sure SD card lines have pull-up resistors in place." , ret);
129+ log_e (" Failed to initialize the card (0x%x ). Make sure SD card lines have pull-up resistors in place." , ret);
85130 }
86131 _card = NULL ;
87132 return false ;
@@ -144,4 +189,4 @@ uint64_t SDMMCFS::usedBytes()
144189}
145190
146191SDMMCFS SD_MMC = SDMMCFS(FSImplPtr(new VFSImpl()));
147- #endif /* CONFIG_IDF_TARGET_ESP32 */
192+ #endif /* SOC_SDMMC_HOST_SUPPORTED */
0 commit comments