diff --git a/.gitmodules b/.gitmodules index 0ad9b79..8b55777 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,6 @@ [submodule "libraries/LittleFS/lib/littlefs"] path = libraries/LittleFS/lib/littlefs url = https://github.com/littlefs-project/littlefs.git -[submodule "libraries/SdFat"] - path = libraries/ESP8266SdFat - url = https://github.com/earlephilhower/ESP8266SdFat.git [submodule "libraries/Keyboard"] path = libraries/HID_Keyboard url = https://github.com/earlephilhower/Keyboard.git @@ -49,3 +46,6 @@ [submodule "libraries/ESPHost"] path = libraries/ESPHost url = https://github.com/Networking-for-Arduino/ESPHost.git +[submodule "libraries/SdFat"] + path = libraries/SdFat + url = https://github.com/greiman/SdFat.git diff --git a/docs/fs.rst b/docs/fs.rst index cf937a8..09800d0 100644 --- a/docs/fs.rst +++ b/docs/fs.rst @@ -174,6 +174,23 @@ second SPI port, ``SPI1``. Just use the following call in place of SD.begin(cspin, SPI1); +Enabling SDIO operation for SD +------------------------------ +SDIO support is available thanks to SdFat implementing a PIO-based SDIO controller. +This mode can significantly increase IO performance to SD cards but it requires that +all 4 DAT0..DAT3 lines to be wired to the Pico (most SD breakout boards only provide +1-but SPI mode of operation). + +To enable SDIO mode, simply specify the SD_CLK, SD_CMD, and SD_DAT0 GPIO pins. The clock +and command pins can be any GPIO (not limited to legal SPI pins). The DAT0 pin can be any +GPIO with remaining DAT1...3 pins consecutively connected. + +..code:: cpp + + SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); + +No other changes are required in the application to take advantage of this high +performance mode. Using VFS (Virtual File System) for POSIX support ------------------------------------------------- diff --git a/libraries/ESP8266SdFat b/libraries/ESP8266SdFat deleted file mode 160000 index 9e14571..0000000 --- a/libraries/ESP8266SdFat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9e1457101ca47b9ace198086dbd8854efc573ccf diff --git a/libraries/SD/examples/CardInfo/CardInfo.ino b/libraries/SD/examples/CardInfo/CardInfo.ino index 1f6d5ab..d69b720 100644 --- a/libraries/SD/examples/CardInfo/CardInfo.ino +++ b/libraries/SD/examples/CardInfo/CardInfo.ino @@ -37,6 +37,11 @@ const int _MOSI = 7; // AKA SPI TX const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + // include the SD library: #include #include @@ -54,21 +59,26 @@ void setup() { Serial.println("\nInitializing SD card..."); bool sdInitialized = false; - // Ensure the SPI pinout the SD card is connected to is configured properly - // Select the correct SPI based on _MISO pin for the RP2040 - if (_MISO == 0 || _MISO == 4 || _MISO == 16) { - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); - sdInitialized = SD.begin(_CS); - } else if (_MISO == 8 || _MISO == 12) { - SPI1.setRX(_MISO); - SPI1.setTX(_MOSI); - SPI1.setSCK(_SCK); - sdInitialized = SD.begin(_CS, SPI1); + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); } else { - Serial.println(F("ERROR: Unknown SPI Configuration")); - return; + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } } if (!sdInitialized) { @@ -114,7 +124,7 @@ void setup() { Serial.println(); // print the type and size of the first FAT-type volume - uint32_t volumesize; + uint64_t volumesize; Serial.print("Volume type is: FAT"); Serial.println(SD.fatType(), DEC); @@ -130,7 +140,7 @@ void setup() { Serial.println((float)volumesize / 1024.0); Serial.print("Card size: "); - Serial.println((float)SD.size() / 1000); + Serial.println((float)SD.size64() / 1000); FSInfo fs_info; SDFS.info(fs_info); diff --git a/libraries/SD/examples/Datalogger/Datalogger.ino b/libraries/SD/examples/Datalogger/Datalogger.ino index bde1a08..b9fd1e7 100644 --- a/libraries/SD/examples/Datalogger/Datalogger.ino +++ b/libraries/SD/examples/Datalogger/Datalogger.ino @@ -30,6 +30,11 @@ const int _MOSI = 7; const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + #include #include @@ -39,13 +44,31 @@ void setup() { Serial.print("Initializing SD card..."); - // Ensure the SPI pinout the SD card is connected to is configured properly - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); + bool sdInitialized = false; + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); + } else { + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } + } // see if the card is present and can be initialized: - if (!SD.begin(_CS)) { + if (!sdInitialized) { Serial.println("Card failed, or not present"); // don't do anything more: return; diff --git a/libraries/SD/examples/DumpFile/DumpFile.ino b/libraries/SD/examples/DumpFile/DumpFile.ino index b06d5cf..ff8c9d4 100644 --- a/libraries/SD/examples/DumpFile/DumpFile.ino +++ b/libraries/SD/examples/DumpFile/DumpFile.ino @@ -30,6 +30,11 @@ const int _MOSI = 7; const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + #include #include @@ -39,13 +44,31 @@ void setup() { Serial.print("Initializing SD card..."); - // Ensure the SPI pinout the SD card is connected to is configured properly - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); + bool sdInitialized = false; + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); + } else { + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } + } // see if the card is present and can be initialized: - if (!SD.begin(_CS)) { + if (!sdInitialized) { Serial.println("Card failed, or not present"); // don't do anything more: return; diff --git a/libraries/SD/examples/Files/Files.ino b/libraries/SD/examples/Files/Files.ino index a4970e6..1b176d3 100644 --- a/libraries/SD/examples/Files/Files.ino +++ b/libraries/SD/examples/Files/Files.ino @@ -28,6 +28,11 @@ const int _MOSI = 7; const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + #include #include @@ -39,12 +44,30 @@ void setup() { Serial.print("Initializing SD card..."); - // Ensure the SPI pinout the SD card is connected to is configured properly - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); + bool sdInitialized = false; + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); + } else { + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } + } - if (!SD.begin(_CS)) { + if (!sdInitialized) { Serial.println("initialization failed!"); return; } diff --git a/libraries/SD/examples/ReadWrite/ReadWrite.ino b/libraries/SD/examples/ReadWrite/ReadWrite.ino index 1de0377..23ea0aa 100644 --- a/libraries/SD/examples/ReadWrite/ReadWrite.ino +++ b/libraries/SD/examples/ReadWrite/ReadWrite.ino @@ -28,6 +28,11 @@ const int _MOSI = 7; const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + #include #include @@ -39,12 +44,30 @@ void setup() { Serial.print("Initializing SD card..."); - // Ensure the SPI pinout the SD card is connected to is configured properly - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); + bool sdInitialized = false; + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); + } else { + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } + } - if (!SD.begin(_CS)) { + if (!sdInitialized) { Serial.println("initialization failed!"); return; } diff --git a/libraries/SD/examples/listfiles/listfiles.ino b/libraries/SD/examples/listfiles/listfiles.ino index 663c24a..3f068d5 100644 --- a/libraries/SD/examples/listfiles/listfiles.ino +++ b/libraries/SD/examples/listfiles/listfiles.ino @@ -42,6 +42,11 @@ const int _MOSI = 7; // AKA SPI TX const int _CS = 5; const int _SCK = 6; +// If you have all 4 DAT pins wired up to the Pico you can use SDIO mode +const int RP_CLK_GPIO = -1; // Set to CLK GPIO +const int RP_CMD_GPIO = -1; // Set to CMD GPIO +const int RP_DAT0_GPIO = -1; // Set to DAT0 GPIO. DAT1..3 must be consecutively connected. + #include #include @@ -58,21 +63,26 @@ void setup() { Serial.println("\nInitializing SD card..."); bool sdInitialized = false; - // Ensure the SPI pinout the SD card is connected to is configured properly - // Select the correct SPI based on _MISO pin for the RP2040 - if (_MISO == 0 || _MISO == 4 || _MISO == 16) { - SPI.setRX(_MISO); - SPI.setTX(_MOSI); - SPI.setSCK(_SCK); - sdInitialized = SD.begin(_CS); - } else if (_MISO == 8 || _MISO == 12) { - SPI1.setRX(_MISO); - SPI1.setTX(_MOSI); - SPI1.setSCK(_SCK); - sdInitialized = SD.begin(_CS, SPI1); + if (RP_CLK_GPIO >= 0) { + // No special requirements on pin locations, this is PIO programmed + sdInitialized = SD.begin(RP_CLK_GPIO, RP_CMD_GPIO, RP_DAT0_GPIO); } else { - Serial.println(F("ERROR: Unknown SPI Configuration")); - return; + // Ensure the SPI pinout the SD card is connected to is configured properly + // Select the correct SPI based on _MISO pin for the RP2040 + if (_MISO == 0 || _MISO == 4 || _MISO == 16) { + SPI.setRX(_MISO); + SPI.setTX(_MOSI); + SPI.setSCK(_SCK); + sdInitialized = SD.begin(_CS); + } else if (_MISO == 8 || _MISO == 12) { + SPI1.setRX(_MISO); + SPI1.setTX(_MOSI); + SPI1.setSCK(_SCK); + sdInitialized = SD.begin(_CS, SPI1); + } else { + Serial.println(F("ERROR: Unknown SPI Configuration")); + return; + } } if (!sdInitialized) { diff --git a/libraries/SD/src/SD.h b/libraries/SD/src/SD.h index 11d51e7..5358e74 100644 --- a/libraries/SD/src/SD.h +++ b/libraries/SD/src/SD.h @@ -36,11 +36,17 @@ public: SDFS.setConfig(SDFSConfig(csPin, SPI_HALF_SPEED, spi)); return SDFS.begin(); } + bool begin(uint8_t csPin, uint32_t cfg = SPI_HALF_SPEED, HardwareSPI &spi = SPI) { SDFS.setConfig(SDFSConfig(csPin, cfg, spi)); return SDFS.begin(); } + bool begin(uint8_t clkPin, uint8_t cmdPin, uint8_t dat0Pin, uint32_t cfg = SD_SCK_MHZ(50)) { + SDFS.setConfig(SDFSConfig(clkPin, cmdPin, dat0Pin, cfg)); + return SDFS.begin(); + } + void end(bool endSPI = true) { SDFS.end(); if (endSPI && _spi) { diff --git a/libraries/SDFS/src/SDFS.cpp b/libraries/SDFS/src/SDFS.cpp index f40653f..ab9434e 100644 --- a/libraries/SDFS/src/SDFS.cpp +++ b/libraries/SDFS/src/SDFS.cpp @@ -63,13 +63,13 @@ FileImplPtr SDFSImpl::open(const char* path, OpenMode openMode, AccessMode acces } free(pathStr); } - File32 fd = _fs.open(path, flags); + FsFile fd = _fs.open(path, flags); if (!fd) { DEBUGV("SDFSImpl::openFile: fd=%p path=`%s` openMode=%d accessMode=%d", &fd, path, openMode, accessMode); return FileImplPtr(); } - auto sharedFd = std::make_shared(fd); + auto sharedFd = std::make_shared(fd); return std::make_shared(this, sharedFd, path); } @@ -88,7 +88,7 @@ DirImplPtr SDFSImpl::openDir(const char* path) { } // At this point we have a name of "/blah/blah/blah" or "blah" or "" // If that references a directory, just open it and we're done. - File32 dirFile; + FsFile dirFile; const char *filter = ""; if (!pathStr[0]) { // openDir("") === openDir("/") @@ -133,7 +133,7 @@ DirImplPtr SDFSImpl::openDir(const char* path) { DEBUGV("SDFSImpl::openDir: path=`%s`\n", path); return DirImplPtr(); } - auto sharedDir = std::make_shared(dirFile); + auto sharedDir = std::make_shared(dirFile); auto ret = std::make_shared(filter, this, sharedDir, pathStr); free(pathStr); return ret; diff --git a/libraries/SDFS/src/SDFS.h b/libraries/SDFS/src/SDFS.h index 7f9886b..8c74979 100644 --- a/libraries/SDFS/src/SDFS.h +++ b/libraries/SDFS/src/SDFS.h @@ -45,7 +45,8 @@ class SDFSConfig : public FSConfig { public: static constexpr uint32_t FSId = 0x53444653; - SDFSConfig(uint8_t csPin = 4, uint32_t spi = SD_SCK_MHZ(10), HardwareSPI &port = SPI) : FSConfig(FSId, false), _csPin(csPin), _part(0), _spiSettings(spi), _spi(&port) { } + SDFSConfig(uint8_t csPin = 4, uint32_t spi = SD_SCK_MHZ(10), HardwareSPI &port = SPI) : FSConfig(FSId, false), _sdio(false), _clkPin(255), _csPin(csPin), _cmdPin(255), _dat0Pin(255), _part(0), _spiSettings(spi), _spi(&port) { } + SDFSConfig(uint8_t clkPin, uint8_t cmdPin, uint8_t dataPin, uint32_t spi = SD_SCK_MHZ(10)) : FSConfig(FSId, false), _sdio(true), _clkPin(clkPin), _cmdPin(cmdPin), _dat0Pin(dataPin), _part(0), _spiSettings(spi), _spi(nullptr) { } SDFSConfig setAutoFormat(bool val = true) { _autoFormat = val; @@ -69,7 +70,11 @@ public: } // Inherit _type and _autoFormat + bool _sdio; + uint8_t _clkPin; // SDIO only; uint8_t _csPin; + uint8_t _cmdPin; // SDIO only + uint8_t _dat0Pin; // SDIO only uint8_t _part; uint32_t _spiSettings; HardwareSPI *_spi; @@ -131,11 +136,20 @@ public: if (_mounted) { return true; } - SdSpiConfig ssc(_cfg._csPin, SHARED_SPI, _cfg._spiSettings, _cfg._spi); - _mounted = _fs.begin(ssc); - if (!_mounted && _cfg._autoFormat) { - format(); + if (!_cfg._sdio) { + SdSpiConfig ssc(_cfg._csPin, SHARED_SPI, _cfg._spiSettings, _cfg._spi); _mounted = _fs.begin(ssc); + if (!_mounted && _cfg._autoFormat) { + format(); + _mounted = _fs.begin(ssc); + } + } else { + SdioConfig ssc(_cfg._clkPin, _cfg._cmdPin, _cfg._dat0Pin); + _mounted = _fs.begin(ssc); + if (!_mounted && _cfg._autoFormat) { + format(); + _mounted = _fs.begin(ssc); + } } FsDateTime::setCallback(dateTimeCB); return _mounted; @@ -153,8 +167,7 @@ public: return false; } bzero(st, sizeof(*st)); - File32 f; - f = _fs.open(path, O_RDONLY); + FsFile f = _fs.open(path, O_RDONLY); if (!f) { return false; } @@ -169,8 +182,8 @@ public: if (f.getCreateDateTime(&date, &time)) { st->ctime = FatToTimeT(date, time); } - if (f.getAccessDate(&date)) { - st->atime = FatToTimeT(date, 0); + if (f.getAccessDateTime(&date, &time)) { + st->atime = FatToTimeT(date, time); } f.close(); return true; @@ -272,7 +285,7 @@ protected: class SDFSFileImpl : public FileImpl { public: - SDFSFileImpl(SDFSImpl *fs, std::shared_ptr fd, const char *name) + SDFSFileImpl(SDFSImpl *fs, std::shared_ptr fd, const char *name) : _fs(fs), _fd(fd), _opened(true) { _name = std::shared_ptr(new char[strlen(name) + 1], std::default_delete()); strcpy(_name.get(), name); @@ -284,7 +297,7 @@ public: } int availableForWrite() override { - return _opened ? _fd->availableSpaceForWrite() : 0; + return _opened ? _fd->availableForWrite() : 0; } size_t write(const uint8_t *buf, size_t size) override { @@ -373,9 +386,9 @@ public: time_t getLastWrite() override { time_t ftime = 0; if (_opened && _fd) { - DirFat_t tmp; - if (_fd.get()->dirEntry(&tmp)) { - ftime = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.modifyDate, *(uint16_t*)tmp.modifyTime); + uint16_t date, time; + if (_fd.get()->getModifyDateTime(&date, &time)) { + ftime = SDFSImpl::FatToTimeT(date, time); } } return ftime; @@ -384,9 +397,9 @@ public: time_t getCreationTime() override { time_t ftime = 0; if (_opened && _fd) { - DirFat_t tmp; - if (_fd.get()->dirEntry(&tmp)) { - ftime = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.createDate, *(uint16_t*)tmp.createTime); + uint16_t date, time; + if (_fd.get()->getCreateDateTime(&date, &time)) { + ftime = SDFSImpl::FatToTimeT(date, time); } } return ftime; @@ -394,14 +407,14 @@ public: protected: SDFSImpl* _fs; - std::shared_ptr _fd; + std::shared_ptr _fd; std::shared_ptr _name; bool _opened; }; class SDFSDirImpl : public DirImpl { public: - SDFSDirImpl(const String& pattern, SDFSImpl* fs, std::shared_ptr dir, const char *dirPath = nullptr) + SDFSDirImpl(const String& pattern, SDFSImpl* fs, std::shared_ptr dir, const char *dirPath = nullptr) : _pattern(pattern), _fs(fs), _dir(dir), _valid(false), _dirPath(nullptr) { if (dirPath) { _dirPath = std::shared_ptr(new char[strlen(dirPath) + 1], std::default_delete()); @@ -466,19 +479,22 @@ public: bool next() override { const int n = _pattern.length(); do { - File32 file; + FsFile file; file.openNext(_dir.get(), O_READ); if (file) { _valid = 1; _size = file.fileSize(); _isFile = file.isFile(); _isDirectory = file.isDir(); - DirFat_t tmp; - if (file.dirEntry(&tmp)) { - _time = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.modifyDate, *(uint16_t*)tmp.modifyTime); - _creation = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.createDate, *(uint16_t*)tmp.createTime); + uint16_t date, time; + if (file.getModifyDateTime(&date, &time)) { + _time = SDFSImpl::FatToTimeT(date, time); } else { _time = 0; + } + if (file.getCreateDateTime(&date, &time)) { + _creation = SDFSImpl::FatToTimeT(date, time); + } else { _creation = 0; } file.getName(_lfn, sizeof(_lfn)); @@ -499,9 +515,9 @@ public: protected: String _pattern; SDFSImpl* _fs; - std::shared_ptr _dir; + std::shared_ptr _dir; bool _valid; - char _lfn[64]; + char _lfn[256]; time_t _time; time_t _creation; std::shared_ptr _dirPath; diff --git a/libraries/SdFat b/libraries/SdFat new file mode 160000 index 0000000..67e2647 --- /dev/null +++ b/libraries/SdFat @@ -0,0 +1 @@ +Subproject commit 67e26476f15a3bae5f390d91b6cc01830920c55d diff --git a/platform.txt b/platform.txt index 56781c1..efde705 100644 --- a/platform.txt +++ b/platform.txt @@ -51,7 +51,7 @@ compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualif compiler.netdefines={build.libpicowdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 compiler.psramdefines={build.psram_cs} {build.psram_freq} -compiler.defines={build.led} {build.usbstack_flags} {build.usbpid} {build.usbvid} {build.usbpwr} {compiler.psramdefines} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} {build.variantdefines} -DARDUINO_VARIANT="{build.variant}" -DPICO_FLASH_SIZE_BYTES={build.flash_total} "@{runtime.platform.path}/lib/{build.chip}/platform_def.txt" +compiler.defines={build.led} {build.usbstack_flags} {build.usbpid} {build.usbvid} {build.usbpwr} {compiler.psramdefines} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} {build.sdfatdefines} {build.variantdefines} -DARDUINO_VARIANT="{build.variant}" -DPICO_FLASH_SIZE_BYTES={build.flash_total} "@{runtime.platform.path}/lib/{build.chip}/platform_def.txt" compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/{build.chip}/platform_inc.txt" "@{runtime.platform.path}/lib/core_inc.txt" "-I{runtime.platform.path}/include" compiler.flags={build.toolchainopts} -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect} {build.picodebugflags} compiler.wrap="@{runtime.platform.path}/lib/{build.chip}/platform_wrap.txt" "@{runtime.platform.path}/lib/core_wrap.txt" @@ -114,6 +114,7 @@ build.espwifitype= build.debugscript=picoprobe_cmsis_dap.tcl build.picodebugflags= build.variantdefines= +build.sdfatdefines=-DFILE_COPY_CONSTRUCTOR_SELECT=FILE_COPY_CONSTRUCTOR_PUBLIC -DUSE_UTF8_LONG_NAMES=1 -DSDFAT_FILE_TYPE=3 -DDISABLE_FS_H_WARNING=1 # Allow Pico boards to be auto-discovered by the IDE #discovery.rp2040.pattern={runtime.tools.pqt-python3.path}/python3 -I "{runtime.platform.path}/tools/pluggable_discovery.py" diff --git a/tests/common.sh b/tests/common.sh index 8069967..290c87a 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -27,6 +27,7 @@ EOL fi # Add items to the following list with "\n" netween them to skip running. No spaces, tabs, etc. allowed read -d '' skiplist << EOL || true +/SdFat/ /#attic/ /AvrAdcLogger/ /examplesV1/ diff --git a/tools/platformio-build.py b/tools/platformio-build.py index 026b958..5b5597b 100755 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -225,6 +225,14 @@ env.Append( "-std=gnu++17", ], + CPPDEFINES=[ + # SdFat definitions required for SDFS + ("FILE_COPY_CONSTRUCTOR_SELECT", "FILE_COPY_CONSTRUCTOR_PUBLIC"), + ("USE_UTF8_LONG_NAMES", "1"), + ("SDFAT_FILE_TYPE", "3"), + ("DISABLE_FS_H_WARNING", "1") + ], + CPPPATH=[ os.path.join(FRAMEWORK_DIR, "cores", "rp2040"), os.path.join(FRAMEWORK_DIR, "cores", "rp2040", "api", "deprecated"),