From 129641321455de64fc2dc858a88f3a77f5443679 Mon Sep 17 00:00:00 2001 From: mcaldwelva Date: Mon, 12 Oct 2020 00:19:24 -0400 Subject: [PATCH 1/4] support extended ASCII filenames, handle hidden/system files --- src/utility/FatStructs.h | 2 +- src/utility/SdFat.h | 2 +- src/utility/SdFile.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utility/FatStructs.h b/src/utility/FatStructs.h index 84c1cc7..35789fd 100644 --- a/src/utility/FatStructs.h +++ b/src/utility/FatStructs.h @@ -413,6 +413,6 @@ static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { } /** Directory entry is for a file or subdirectory */ static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { - return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; + return (dir->attributes & (DIR_ATT_VOLUME_ID | DIR_ATT_SYSTEM | DIR_ATT_HIDDEN)) == 0; } #endif // FatStructs_h diff --git a/src/utility/SdFat.h b/src/utility/SdFat.h index 46b880b..3c1edee 100644 --- a/src/utility/SdFat.h +++ b/src/utility/SdFat.h @@ -437,7 +437,7 @@ class SdFile : public Print { // private data uint8_t flags_; // See above for definition of flags_ bits - uint8_t type_; // type of file see above for values + uint8_t volatile type_; // type of file see above for values uint32_t curCluster_; // cluster for current file position uint32_t curPosition_; // current file position in bytes from beginning uint32_t dirBlock_; // SD block that contains directory entry for file diff --git a/src/utility/SdFile.cpp b/src/utility/SdFile.cpp index 18a1db6..b433fa2 100644 --- a/src/utility/SdFile.cpp +++ b/src/utility/SdFile.cpp @@ -303,19 +303,19 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) { // illegal FAT characters uint8_t b; #if defined(__AVR__) - PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + PGM_P p = PSTR("|<>:+=?/[];,*\"\\"); while ((b = pgm_read_byte(p++))) if (b == c) { return false; } #elif defined(__arm__) - const uint8_t valid[] = "|<>^+=?/[];,*\"\\"; + const uint8_t valid[] = "|<>:+=?/[];,*\"\\"; const uint8_t *p = valid; while ((b = *p++)) if (b == c) { return false; } #endif // check size and only allow ASCII printable characters - if (i > n || c < 0X21 || c > 0X7E) { + if (i > n || c < 0x20 || c == 0x7F) { return false; } // only upper case allowed in 8.3 names - convert lower to upper @@ -1041,7 +1041,7 @@ uint8_t SdFile::rmRfStar(void) { } // skip if part of long file name or volume label in root - if (!DIR_IS_FILE_OR_SUBDIR(p)) { + if (p->attributes & DIR_ATT_VOLUME_ID) { continue; } From 16acc15aa436f09338f3bba9754ee8ec21e69902 Mon Sep 17 00:00:00 2001 From: mcaldwelva Date: Tue, 3 Nov 2020 12:13:28 -0500 Subject: [PATCH 2/4] improved support for and 0xE5 in filenames --- src/utility/SdFile.cpp | 46 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/utility/SdFile.cpp b/src/utility/SdFile.cpp index b433fa2..aabbbda 100644 --- a/src/utility/SdFile.cpp +++ b/src/utility/SdFile.cpp @@ -203,16 +203,20 @@ uint8_t SdFile::dirEntry(dir_t* dir) { \param[out] name A 13 byte char array for the formatted name. */ void SdFile::dirName(const dir_t& dir, char* name) { - uint8_t j = 0; - for (uint8_t i = 0; i < 11; i++) { - if (dir.name[i] == ' ') { - continue; - } + uint8_t i = 0, j = 0; + // unescape first character + if ((uint8_t) dir.name[i] == DIR_NAME_0XE5) { + name[j++] = 0xE5; + i++; + } + for (; i < 11; i++) { if (i == 8) { + while (j > 0 && name[j-1] == ' ') j--; name[j++] = '.'; } name[j++] = dir.name[i]; } + while (name[j-1] == ' ') j--; name[j] = 0; } //------------------------------------------------------------------------------ @@ -288,10 +292,12 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) { uint8_t n = 7; // max index for part before dot uint8_t i = 0; // blank fill name and extension - while (i < 11) { - name[i++] = ' '; + memset(name, ' ', 11); + // escape first character + if ((uint8_t) *str == 0xE5) { + name[i++] = DIR_NAME_0XE5; + str++; } - i = 0; while ((c = *str++) != '\0') { if (c == '.') { if (n == 10) { @@ -301,16 +307,12 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) { i = 8; // place for extension } else { // illegal FAT characters - uint8_t b; #if defined(__AVR__) - PGM_P p = PSTR("|<>:+=?/[];,*\"\\"); - while ((b = pgm_read_byte(p++))) if (b == c) { + if (strchr_P(PSTR("|<>:+=?/[];,*\"\\"), c)) { return false; } - #elif defined(__arm__) - const uint8_t valid[] = "|<>:+=?/[];,*\"\\"; - const uint8_t *p = valid; - while ((b = *p++)) if (b == c) { + #else + if (strchr("|<>:+=?/[];,*\"\\", c)) { return false; } #endif @@ -323,7 +325,7 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) { } } // must have a file name, extension is optional - return name[0] != ' '; + return i > 0; } //------------------------------------------------------------------------------ /** Make a new directory. @@ -690,11 +692,13 @@ uint8_t SdFile::openRoot(SdVolume* vol) { \param[in] width Blank fill name if length is less than \a width. */ void SdFile::printDirName(const dir_t& dir, uint8_t width) { - uint8_t w = 0; - for (uint8_t i = 0; i < 11; i++) { - if (dir.name[i] == ' ') { - continue; - } + uint8_t i = 0, w = 0; + // unescape first character + if ((uint8_t) dir.name[i] == DIR_NAME_0XE5) { + Serial.write(0xE5); + i++; w++; + } + for (; i < 11; i++) { if (i == 8) { Serial.print('.'); w++; From a9b2d4ba5c388449f6f2b497ac05e4421b028ba8 Mon Sep 17 00:00:00 2001 From: mcaldwelva Date: Mon, 10 May 2021 22:32:48 -0400 Subject: [PATCH 3/4] release pins/deref SPI when done --- src/SD.cpp | 1 + src/utility/Sd2Card.cpp | 26 ++++++++++++++++++++++++++ src/utility/Sd2Card.h | 1 + 3 files changed, 28 insertions(+) diff --git a/src/SD.cpp b/src/SD.cpp index 24fcb2e..8006f38 100644 --- a/src/SD.cpp +++ b/src/SD.cpp @@ -367,6 +367,7 @@ namespace SDLib { //call this when a card is removed. It will allow you to insert and initialise a new card. void SDClass::end() { root.close(); + card.done(); } // this little helper is used to traverse paths diff --git a/src/utility/Sd2Card.cpp b/src/utility/Sd2Card.cpp index 7cfbe73..1de0c4a 100644 --- a/src/utility/Sd2Card.cpp +++ b/src/utility/Sd2Card.cpp @@ -358,6 +358,32 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { return false; } //------------------------------------------------------------------------------ +/** + Return initialized pins to floating and dereference SPI lib. +*/ +void Sd2Card::done() { + pinMode(chipSelectPin_, INPUT); + digitalWrite(chipSelectPin_, LOW); + + #ifndef USE_SPI_LIB + pinMode(SPI_MISO_PIN, INPUT); + digitalWrite(SPI_MISO_PIN, LOW); + pinMode(SPI_MOSI_PIN, INPUT); + digitalWrite(SPI_MOSI_PIN, LOW); + pinMode(SPI_SCK_PIN, INPUT); + digitalWrite(SPI_SCK_PIN, LOW); + #endif + + #ifndef SOFTWARE_SPI + #ifndef USE_SPI_LIB + pinMode(SS_PIN, INPUT); + digitalWrite(SS_PIN, LOW); + #else // USE_SPI_LIB + SDCARD_SPI.end(); + #endif // USE_SPI_LIB + #endif // SOFTWARE_SPI +} +//------------------------------------------------------------------------------ /** Enable or disable partial block reads. diff --git a/src/utility/Sd2Card.h b/src/utility/Sd2Card.h index 5d91ebf..fe09839 100644 --- a/src/utility/Sd2Card.h +++ b/src/utility/Sd2Card.h @@ -206,6 +206,7 @@ class Sd2Card { return init(sckRateID, SD_CHIP_SELECT_PIN); } uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin); + void done(); void partialBlockRead(uint8_t value); /** Returns the current value, true or false, for partial block read. */ uint8_t partialBlockRead(void) const { From 58bcbb6af1afe36a26ff11fa46803ae7d78e73e8 Mon Sep 17 00:00:00 2001 From: mcaldwelva Date: Tue, 13 Sep 2022 23:38:30 -0400 Subject: [PATCH 4/4] implement pr #97 --- src/SD.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SD.cpp b/src/SD.cpp index 544c94d..88d52eb 100644 --- a/src/SD.cpp +++ b/src/SD.cpp @@ -616,7 +616,8 @@ namespace SDLib { //Serial.print("try to open file "); //Serial.println(name); - if (f.open(_file, name, mode)) { + uint16_t index = _file->curPosition() / sizeof(dir_t) - 1; + if (f.open(_file, index, mode)) { //Serial.println("OK!"); return File(f, name); } else {