From ef5a4cd8070105e518095ebc414bc3bb00dea20c Mon Sep 17 00:00:00 2001 From: Larry Bernstone Date: Thu, 6 Jun 2024 08:29:53 -1000 Subject: [PATCH 1/4] feat(sdmmc): Add RAW disk functions feat(sdmmc): fixed printf mismatches and missing callback feat(sdmmc): added ci.json Removed excess log_i --- .../SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino | 94 +++++++++++++++++++ libraries/SD_MMC/examples/SD2USBMSC/ci.json | 9 ++ libraries/SD_MMC/src/SD_MMC.cpp | 22 +++++ libraries/SD_MMC/src/SD_MMC.h | 9 +- 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino create mode 100644 libraries/SD_MMC/examples/SD2USBMSC/ci.json diff --git a/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino new file mode 100644 index 00000000000..7c600a148aa --- /dev/null +++ b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino @@ -0,0 +1,94 @@ +#ifndef ARDUINO_USB_MODE +#error This sketch requires a device capable of USB-OTG +#endif + +#include +#include +#include + +// USB Mass Storage Class (MSC) object +USBMSC msc; + +int clk = 36; +int cmd = 35; +int d0 = 37; +int d1 = 38; +int d2 = 33; +int d3 = 34; +bool onebit = true; // set to false for 4-bit. 1-bit will ignore the d1-d3 pins (but d3 must be pulled high) + +static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){ + uint32_t secSize = SD_MMC.sectorSize(); + if (!secSize) return false; // disk error + log_v("Write lba: %ld\toffset: %ld\tbufsize: %ld", lba, offset, bufsize); + for (int x=0; x< bufsize/secSize; x++) { + uint8_t blkbuffer[secSize]; + memcpy(blkbuffer, (uint8_t*)buffer + secSize*x, secSize); + if (!SD_MMC.writeRAW(blkbuffer, lba + x)) return false; + } + return bufsize; +} + +static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){ + uint32_t secSize = SD_MMC.sectorSize(); + if (!secSize) return false; // disk error + log_v("Read lba: %ld\toffset: %ld\tbufsize: %ld\tsector: %lu", lba, offset, bufsize, secSize); + for (int x=0; x < bufsize/secSize; x++) { + if (!SD_MMC.readRAW((uint8_t*)buffer + (x * secSize), lba + x)) return false; // outside of volume boundary + } + return bufsize; +} + +static bool onStartStop(uint8_t power_condition, bool start, bool load_eject){ + log_i("Start/Stop power: %u\tstart: %d\teject: %d", power_condition, start, load_eject); + return true; +} + +static void usbEventCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if (event_base == ARDUINO_USB_EVENTS) { + arduino_usb_event_data_t *data = (arduino_usb_event_data_t *)event_data; + switch (event_id) { + case ARDUINO_USB_STARTED_EVENT: Serial.println("USB PLUGGED"); break; + case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); break; + case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); break; + case ARDUINO_USB_RESUME_EVENT: Serial.println("USB RESUMED"); break; + + default: break; + } + } +} + +void setup(){ + Serial.begin(115200); + Serial.println("Starting Serial"); + + Serial.println("Mounting SDcard"); + SD_MMC.setPins(clk, cmd, d0, d1, d2, d3); + if(!SD_MMC.begin("/sdcard", onebit)){ + Serial.println("Mount Failed"); + return; + } + + Serial.println("Initializing MSC"); + // Initialize USB metadata and callbacks for MSC (Mass Storage Class) + msc.vendorID("ESP32"); + msc.productID("USB_MSC"); + msc.productRevision("1.0"); + msc.onRead(onRead); + msc.onWrite(onWrite); + msc.onStartStop(onStartStop); + msc.mediaPresent(true); + msc.begin(SD_MMC.numSectors(), SD_MMC.sectorSize()); + + Serial.println("Initializing USB"); + + USB.begin(); + USB.onEvent(usbEventCallback); + + Serial.printf("Card Size: %lluMB\n", SD_MMC.totalBytes()/1024/1024); + Serial.printf("Sector: %d\tCount: %d\n", SD_MMC.sectorSize(), SD_MMC.numSectors()); +} + +void loop(){ + delay(-1); +} diff --git a/libraries/SD_MMC/examples/SD2USBMSC/ci.json b/libraries/SD_MMC/examples/SD2USBMSC/ci.json new file mode 100644 index 00000000000..2a5ca52e079 --- /dev/null +++ b/libraries/SD_MMC/examples/SD2USBMSC/ci.json @@ -0,0 +1,9 @@ +{ + "targets": { + "esp32": false, + "esp32s2": false, + "esp32c3": false, + "esp32c6": false, + "esp32h2": false + } +} diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index 18aa9169f59..86968b3917e 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -26,6 +26,8 @@ #include "driver/sdmmc_host.h" #include "driver/sdmmc_defs.h" #include "sdmmc_cmd.h" +#include "diskio_sdmmc.h" +#include "diskio.h" #include "soc/sdmmc_pins.h" #include "ff.h" #include "esp32-hal-periman.h" @@ -191,6 +193,8 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_ return false; } _impl->mountpoint(mountpoint); + _pdrv = ff_diskio_get_pdrv_card(_card); + if (!perimanSetPinBus(_pin_cmd, ESP32_BUS_TYPE_SDMMC_CMD, (void *)(this), -1, -1)) { goto err; @@ -280,5 +284,23 @@ uint64_t SDMMCFS::usedBytes() { return size; } +int SDMMCFS::sectorSize() { + if (!_card) return 0; + return _card->csd.sector_size; +} + +int SDMMCFS::numSectors() { + if (!_card) return 0; + return (totalBytes()/_card->csd.sector_size); +} + +bool SDMMCFS::readRAW(uint8_t* buffer, uint32_t sector) { + return (disk_read(_pdrv, buffer, sector, 1) == 0); +} + +bool SDMMCFS::writeRAW(uint8_t *buffer, uint32_t sector) { + return (disk_write(_pdrv, buffer, sector, 1) == 0); +} + SDMMCFS SD_MMC = SDMMCFS(FSImplPtr(new VFSImpl())); #endif /* SOC_SDMMC_HOST_SUPPORTED */ diff --git a/libraries/SD_MMC/src/SD_MMC.h b/libraries/SD_MMC/src/SD_MMC.h index 3a69850470c..0cf2a71469d 100644 --- a/libraries/SD_MMC/src/SD_MMC.h +++ b/libraries/SD_MMC/src/SD_MMC.h @@ -16,7 +16,9 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" -#ifdef SOC_SDMMC_HOST_SUPPORTED +#ifndef SOC_SDMMC_HOST_SUPPORTED +#error The SDMMC library requires a device with an SDIO Host +#else #include "FS.h" #include "driver/sdmmc_types.h" @@ -40,6 +42,7 @@ class SDMMCFS : public FS { int8_t _pin_d1 = -1; int8_t _pin_d2 = -1; int8_t _pin_d3 = -1; + uint8_t _pdrv = 0xFF; bool _mode1bit = false; public: @@ -55,6 +58,10 @@ class SDMMCFS : public FS { uint64_t cardSize(); uint64_t totalBytes(); uint64_t usedBytes(); + int sectorSize(); + int numSectors(); + bool readRAW(uint8_t *buffer, uint32_t sector); + bool writeRAW(uint8_t *buffer, uint32_t sector); private: static bool sdmmcDetachBus(void *bus_pointer); From d22d5d14c599d6df65043a0654328839f5b9c76e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:13:05 +0000 Subject: [PATCH 2/4] ci(pre-commit): Apply automatic fixes --- .../SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino | 38 +++++++++++-------- libraries/SD_MMC/src/SD_MMC.cpp | 13 ++++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino index 7c600a148aa..6070d346cda 100644 --- a/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino +++ b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino @@ -15,31 +15,39 @@ int d0 = 37; int d1 = 38; int d2 = 33; int d3 = 34; -bool onebit = true; // set to false for 4-bit. 1-bit will ignore the d1-d3 pins (but d3 must be pulled high) +bool onebit = true; // set to false for 4-bit. 1-bit will ignore the d1-d3 pins (but d3 must be pulled high) -static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){ +static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) { uint32_t secSize = SD_MMC.sectorSize(); - if (!secSize) return false; // disk error + if (!secSize) { + return false; // disk error + } log_v("Write lba: %ld\toffset: %ld\tbufsize: %ld", lba, offset, bufsize); - for (int x=0; x< bufsize/secSize; x++) { + for (int x = 0; x < bufsize / secSize; x++) { uint8_t blkbuffer[secSize]; - memcpy(blkbuffer, (uint8_t*)buffer + secSize*x, secSize); - if (!SD_MMC.writeRAW(blkbuffer, lba + x)) return false; + memcpy(blkbuffer, (uint8_t *)buffer + secSize * x, secSize); + if (!SD_MMC.writeRAW(blkbuffer, lba + x)) { + return false; + } } return bufsize; } -static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){ +static int32_t onRead(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { uint32_t secSize = SD_MMC.sectorSize(); - if (!secSize) return false; // disk error + if (!secSize) { + return false; // disk error + } log_v("Read lba: %ld\toffset: %ld\tbufsize: %ld\tsector: %lu", lba, offset, bufsize, secSize); - for (int x=0; x < bufsize/secSize; x++) { - if (!SD_MMC.readRAW((uint8_t*)buffer + (x * secSize), lba + x)) return false; // outside of volume boundary + for (int x = 0; x < bufsize / secSize; x++) { + if (!SD_MMC.readRAW((uint8_t *)buffer + (x * secSize), lba + x)) { + return false; // outside of volume boundary + } } return bufsize; } -static bool onStartStop(uint8_t power_condition, bool start, bool load_eject){ +static bool onStartStop(uint8_t power_condition, bool start, bool load_eject) { log_i("Start/Stop power: %u\tstart: %d\teject: %d", power_condition, start, load_eject); return true; } @@ -58,13 +66,13 @@ static void usbEventCallback(void *arg, esp_event_base_t event_base, int32_t eve } } -void setup(){ +void setup() { Serial.begin(115200); Serial.println("Starting Serial"); Serial.println("Mounting SDcard"); SD_MMC.setPins(clk, cmd, d0, d1, d2, d3); - if(!SD_MMC.begin("/sdcard", onebit)){ + if (!SD_MMC.begin("/sdcard", onebit)) { Serial.println("Mount Failed"); return; } @@ -85,10 +93,10 @@ void setup(){ USB.begin(); USB.onEvent(usbEventCallback); - Serial.printf("Card Size: %lluMB\n", SD_MMC.totalBytes()/1024/1024); + Serial.printf("Card Size: %lluMB\n", SD_MMC.totalBytes() / 1024 / 1024); Serial.printf("Sector: %d\tCount: %d\n", SD_MMC.sectorSize(), SD_MMC.numSectors()); } -void loop(){ +void loop() { delay(-1); } diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index 86968b3917e..13e5fcf27fc 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -195,7 +195,6 @@ bool SDMMCFS::begin(const char *mountpoint, bool mode1bit, bool format_if_mount_ _impl->mountpoint(mountpoint); _pdrv = ff_diskio_get_pdrv_card(_card); - if (!perimanSetPinBus(_pin_cmd, ESP32_BUS_TYPE_SDMMC_CMD, (void *)(this), -1, -1)) { goto err; } @@ -285,16 +284,20 @@ uint64_t SDMMCFS::usedBytes() { } int SDMMCFS::sectorSize() { - if (!_card) return 0; + if (!_card) { + return 0; + } return _card->csd.sector_size; } int SDMMCFS::numSectors() { - if (!_card) return 0; - return (totalBytes()/_card->csd.sector_size); + if (!_card) { + return 0; + } + return (totalBytes() / _card->csd.sector_size); } -bool SDMMCFS::readRAW(uint8_t* buffer, uint32_t sector) { +bool SDMMCFS::readRAW(uint8_t *buffer, uint32_t sector) { return (disk_read(_pdrv, buffer, sector, 1) == 0); } From 83ff659b6992361303edda75b66bc2779f405c6a Mon Sep 17 00:00:00 2001 From: Larry Bernstone Date: Fri, 7 Jun 2024 07:37:42 -1000 Subject: [PATCH 3/4] Fixed sdmmc host check to pass CI --- libraries/SD_MMC/src/SD_MMC.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/SD_MMC/src/SD_MMC.h b/libraries/SD_MMC/src/SD_MMC.h index 0cf2a71469d..a2bc12aed64 100644 --- a/libraries/SD_MMC/src/SD_MMC.h +++ b/libraries/SD_MMC/src/SD_MMC.h @@ -17,7 +17,9 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" #ifndef SOC_SDMMC_HOST_SUPPORTED -#error The SDMMC library requires a device with an SDIO Host +#ifdef ARDUINO +#warning The SDMMC library requires a device with an SDIO Host +#endif #else #include "FS.h" From c92bd43c8565f1da70d84eb26de424d077969376 Mon Sep 17 00:00:00 2001 From: Larry Bernstone Date: Tue, 11 Jun 2024 11:44:51 -1000 Subject: [PATCH 4/4] feat(sdmmc): fixed example USB check --- libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino index 6070d346cda..d379e409960 100644 --- a/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino +++ b/libraries/SD_MMC/examples/SD2USBMSC/SD2USBMSC.ino @@ -1,5 +1,5 @@ -#ifndef ARDUINO_USB_MODE -#error This sketch requires a device capable of USB-OTG +#if !SOC_USB_OTG_SUPPORTED || ARDUINO_USB_MODE +#error Device does not support USB_OTG or native USB CDC/JTAG is selected #endif #include