diff --git a/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino b/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino index 030caae759c..e03f5ceb25e 100644 --- a/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino +++ b/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino @@ -14,6 +14,7 @@ * Connections for ║ ║ ╔═══╩═║═║═══╗ ║ ║ ║ * full-sized ║ ║ ║ ╔═╝ ║ ║ ║ ║ ║ * SD card ║ ║ ║ ║ ║ ║ ║ ║ ║ + * ESP32-P4 Func EV | 40 39 GND 43 3V3 GND 44 43 42 | SLOT 0 (IO_MUX) * ESP32-S3 DevKit | 21 47 GND 39 3V3 GND 40 41 42 | * ESP32-S3-USB-OTG | 38 37 GND 36 3V3 GND 35 34 33 | * ESP32 | 4 2 GND 14 3V3 GND 15 13 12 | @@ -42,6 +43,7 @@ #include "FS.h" #include "SD_MMC.h" +#ifdef CONFIG_IDF_TARGET_ESP32S3 // Default pins for ESP-S3 // Warning: ESP32-S3-WROOM-2 is using most of the default GPIOs (33-37) to interface with on-board OPI flash. // If the SD_MMC is initialized with default pins it will result in rebooting loop - please @@ -54,6 +56,7 @@ int d0 = 37; int d1 = 38; int d2 = 33; int d3 = 39; // GPIO 34 is not broken-out on ESP32-S3-DevKitC-1 v1.1 +#endif void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.printf("Listing directory: %s\n", dirname); @@ -211,15 +214,16 @@ void testFileIO(fs::FS &fs, const char *path) { void setup() { Serial.begin(115200); /* - // If you want to change the pin assignment on ESP32-S3 uncomment this block and the appropriate + // If you want to change the pin assignment or you get an error that some pins + // are not assigned on ESP32-S3/ESP32-P4 uncomment this block and the appropriate // line depending if you want to use 1-bit or 4-bit line. - // Please note that ESP32 does not allow pin change and will always fail. + // Please note that ESP32 does not allow pin change and setPins() will always fail. //if(! SD_MMC.setPins(clk, cmd, d0)){ //if(! SD_MMC.setPins(clk, cmd, d0, d1, d2, d3)){ - Serial.println("Pin change failed!"); - return; - } - */ + // Serial.println("Pin change failed!"); + // return; + //} + */ if (!SD_MMC.begin()) { Serial.println("Card Mount Failed"); @@ -262,4 +266,6 @@ void setup() { Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024)); } -void loop() {} +void loop() { + delay(10); +} diff --git a/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino b/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino index bd9f150f3e8..d1e933e4f4b 100644 --- a/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino +++ b/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino @@ -14,6 +14,7 @@ * Connections for ║ ║ ╔═══╩═║═║═══╗ ║ ║ ║ * full-sized ║ ║ ║ ╔═╝ ║ ║ ║ ║ ║ * SD card ║ ║ ║ ║ ║ ║ ║ ║ ║ + * ESP32-P4 Func EV | 40 39 GND 43 3V3 GND 44 43 42 | SLOT 0 (IO_MUX) * ESP32-S3 DevKit | 21 47 GND 39 3V3 GND 40 41 42 | * ESP32-S3-USB-OTG | 38 37 GND 36 3V3 GND 35 34 33 | * ESP32 | 4 2 GND 14 3V3 GND 15 13 12 | diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index 80cb150baa2..4a0962ff7e4 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -32,11 +32,14 @@ #include "ff.h" #include "esp32-hal-periman.h" +#if SOC_SDMMC_IO_POWER_EXTERNAL +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif + using namespace fs; SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) { -#if !defined(CONFIG_IDF_TARGET_ESP32P4) -#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC) +#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && defined(BOARD_HAS_SDMMC) && !defined(CONFIG_IDF_TARGET_ESP32P4) _pin_clk = SDMMC_CLK; _pin_cmd = SDMMC_CMD; _pin_d0 = SDMMC_D0; @@ -45,9 +48,8 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) { _pin_d2 = SDMMC_D2; _pin_d3 = SDMMC_D3; #endif // BOARD_HAS_1BIT_SDMMC -#endif // !defined(CONFIG_IDF_TARGET_ESP32P4) -#elif SOC_SDMMC_USE_IOMUX && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32) +#elif defined(SOC_SDMMC_USE_IOMUX) && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32) _pin_clk = SDMMC_SLOT1_IOMUX_PIN_NUM_CLK; _pin_cmd = SDMMC_SLOT1_IOMUX_PIN_NUM_CMD; _pin_d0 = SDMMC_SLOT1_IOMUX_PIN_NUM_D0; @@ -57,7 +59,9 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) { _pin_d3 = SDMMC_SLOT1_IOMUX_PIN_NUM_D3; #endif // BOARD_HAS_1BIT_SDMMC -#elif SOC_SDMMC_USE_IOMUX && defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32P4) +// ESP32-P4 can use either IOMUX or GPIO matrix +#elif defined(BOARD_HAS_SDMMC) && defined(CONFIG_IDF_TARGET_ESP32P4) +#if defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0) _pin_clk = SDMMC_SLOT0_IOMUX_PIN_NUM_CLK; _pin_cmd = SDMMC_SLOT0_IOMUX_PIN_NUM_CMD; _pin_d0 = SDMMC_SLOT0_IOMUX_PIN_NUM_D0; @@ -66,6 +70,19 @@ SDMMCFS::SDMMCFS(FSImplPtr impl) : FS(impl), _card(nullptr) { _pin_d2 = SDMMC_SLOT0_IOMUX_PIN_NUM_D2; _pin_d3 = SDMMC_SLOT0_IOMUX_PIN_NUM_D3; #endif // BOARD_HAS_1BIT_SDMMC +#else + _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 // BOARD_SDMMC_SLOT_NO +#endif +#if defined(SOC_SDMMC_IO_POWER_EXTERNAL) && defined(BOARD_SDMMC_POWER_CHANNEL) + _power_channel = BOARD_SDMMC_POWER_CHANNEL; #endif } @@ -95,7 +112,7 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) { d2 = digitalPinToGPIONumber(d2); d3 = digitalPinToGPIONumber(d3); -#ifdef SOC_SDMMC_USE_GPIO_MATRIX +#if defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4) // 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; @@ -116,11 +133,42 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) { return false; } return true; +#elif defined(CONFIG_IDF_TARGET_ESP32P4) +#if defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0) + // ESP32-P4 can use either IOMUX or GPIO matrix + bool pins_ok = + (clk == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_CLK) && (cmd == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_CMD) && (d0 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D0) + && (((d1 == -1) && (d2 == -1) && (d3 == -1)) || ((d1 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D1) && (d2 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D2) && (d3 == (int)SDMMC_SLOT0_IOMUX_PIN_NUM_D3))); + if (!pins_ok) { + log_e("SDMMCFS: specified pins are not supported when using IOMUX (SDMMC SLOT 0)."); + return false; + } + return true; +#else + _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; +#endif #else #error SoC not supported #endif } +#ifdef SOC_SDMMC_IO_POWER_EXTERNAL +bool SDMMCFS::setPowerChannel(int power_channel) { + if (_card != nullptr) { + log_e("SD_MMC.setPowerChannel must be called before SD_MMC.begin"); + return false; + } + _power_channel = power_channel; + return true; +} +#endif + bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed, int sdmmc_frequency, uint8_t maxOpenFiles) { if (_card) { return true; @@ -135,7 +183,9 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_ } //mount sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); -#ifdef SOC_SDMMC_USE_GPIO_MATRIX +#if (defined(SOC_SDMMC_USE_GPIO_MATRIX) && !defined(CONFIG_IDF_TARGET_ESP32P4)) \ + || (defined(CONFIG_IDF_TARGET_ESP32P4) && ((defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 1)) || !defined(BOARD_HAS_SDMMC))) + log_d("pin_cmd: %d, pin_clk: %d, pin_d0: %d, pin_d1: %d, pin_d2: %d, pin_d3: %d", _pin_cmd, _pin_clk, _pin_d0, _pin_d1, _pin_d2, _pin_d3); // SoC supports SDMMC pin configuration via GPIO matrix. // Check 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))) { @@ -175,7 +225,18 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_ sdmmc_host_t host = SDMMC_HOST_DEFAULT(); host.flags = SDMMC_HOST_FLAG_4BIT; +#if defined(CONFIG_IDF_TARGET_ESP32P4) && defined(BOARD_SDMMC_SLOT) && (BOARD_SDMMC_SLOT == 0) + host.slot = SDMMC_HOST_SLOT_0; + // reconfigure slot_config to remove all pins in order to use IO_MUX + slot_config = { + .cd = SDMMC_SLOT_NO_CD, + .wp = SDMMC_SLOT_NO_WP, + .width = 4, + .flags = 0, + }; +#else host.slot = SDMMC_HOST_SLOT_1; +#endif host.max_freq_khz = sdmmc_frequency; #ifdef BOARD_HAS_1BIT_SDMMC mode1bit = true; @@ -186,6 +247,34 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_ } _mode1bit = mode1bit; +#ifdef SOC_SDMMC_IO_POWER_EXTERNAL + if (_power_channel == -1) { + log_i("On-chip power channel specified, use external power for SDMMC"); + } else { + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = _power_channel, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + if (sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle) != ESP_OK) { + log_e("Failed to create a new on-chip LDO power control driver"); + return false; + } + host.pwr_ctrl_handle = pwr_ctrl_handle; + } +#endif + +#if defined(BOARD_SDMMC_POWER_PIN) +#ifndef BOARD_SDMMC_POWER_ON_LEVEL +#error "BOARD_SDMMC_POWER_ON_LEVEL not defined, please define it in pins_arduino.h" +#endif + pinMode(BOARD_SDMMC_POWER_PIN, OUTPUT); + digitalWrite(BOARD_SDMMC_POWER_PIN, !BOARD_SDMMC_POWER_ON_LEVEL); + delay(200); + digitalWrite(BOARD_SDMMC_POWER_PIN, BOARD_SDMMC_POWER_ON_LEVEL); + perimanSetPinBusExtraType(BOARD_SDMMC_POWER_PIN, "SDMMC_POWER"); +#endif + esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = format_if_mount_failed, .max_files = maxOpenFiles, @@ -252,6 +341,9 @@ void SDMMCFS::end() { perimanClearPinBus(_pin_d2); perimanClearPinBus(_pin_d3); } +#if defined(BOARD_SDMMC_POWER_PIN) + perimanClearPinBus(BOARD_SDMMC_POWER_PIN); +#endif } } diff --git a/libraries/SD_MMC/src/SD_MMC.h b/libraries/SD_MMC/src/SD_MMC.h index a2bc12aed64..b6fe13a0d24 100644 --- a/libraries/SD_MMC/src/SD_MMC.h +++ b/libraries/SD_MMC/src/SD_MMC.h @@ -44,6 +44,9 @@ class SDMMCFS : public FS { int8_t _pin_d1 = -1; int8_t _pin_d2 = -1; int8_t _pin_d3 = -1; +#ifdef SOC_SDMMC_IO_POWER_EXTERNAL + int8_t _power_channel = -1; +#endif uint8_t _pdrv = 0xFF; bool _mode1bit = false; @@ -51,6 +54,9 @@ class SDMMCFS : public FS { 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); +#ifdef SOC_SDMMC_IO_POWER_EXTERNAL + bool setPowerChannel(int power_channel); +#endif bool begin( const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false, int sdmmc_frequency = BOARD_MAX_SDMMC_FREQ, uint8_t maxOpenFiles = 5 diff --git a/variants/esp32p4/pins_arduino.h b/variants/esp32p4/pins_arduino.h index 792146f5ca2..cbb1e871ae5 100644 --- a/variants/esp32p4/pins_arduino.h +++ b/variants/esp32p4/pins_arduino.h @@ -4,15 +4,6 @@ #include #include "soc/soc_caps.h" -#define PIN_NEOPIXEL 44 -// BUILTIN_LED can be used in new Arduino API digitalWrite() like in Blink.ino -static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + PIN_NEOPIXEL; -#define BUILTIN_LED LED_BUILTIN // backward compatibility -#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN -// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API rgbLedWrite() -#define RGB_BUILTIN LED_BUILTIN -#define RGB_BRIGHTNESS 64 - // BOOT_MODE 35 // BOOT_MODE2 36 pullup @@ -58,6 +49,8 @@ static const uint8_t T11 = 13; static const uint8_t T12 = 14; static const uint8_t T13 = 15; +/* ESP32-P4 EV Function board specific definitions */ +//ETH #define ETH_PHY_TYPE ETH_PHY_TLK110 #define ETH_PHY_ADDR 1 #define ETH_PHY_MDC 31 @@ -72,4 +65,21 @@ static const uint8_t T13 = 15; #define ETH_RMII_CLK 50 #define ETH_CLK_MODE EMAC_CLK_EXT_IN +//SDMMC +#define BOARD_HAS_SDMMC +#define BOARD_SDMMC_SLOT 0 +#define BOARD_SDMMC_POWER_CHANNEL 4 +#define BOARD_SDMMC_POWER_PIN 45 +#define BOARD_SDMMC_POWER_ON_LEVEL LOW + +//WIFI - ESP32C6 +#define BOARD_HAS_SDIO_ESP_HOSTED +#define BOARD_SDIO_ESP_HOSTED_CLK 18 +#define BOARD_SDIO_ESP_HOSTED_CMD 19 +#define BOARD_SDIO_ESP_HOSTED_D0 14 +#define BOARD_SDIO_ESP_HOSTED_D1 15 +#define BOARD_SDIO_ESP_HOSTED_D2 16 +#define BOARD_SDIO_ESP_HOSTED_D3 17 +#define BOARD_SDIO_ESP_HOSTED_RESET 54 + #endif /* Pins_Arduino_h */