Teensyduino File System Integration, including MTP and MSC

Strange can’t remember what my Samsung sd cards default to. But as I said my ExFat drives definitely work.
 
Thanks again Mike :)

Yes ExFat is supported. Running 64gb exfat usb stick for my tests.

Have to remember windows and sdfat both will format 32gb and above as ExFat. And in the case of windows ntfs or ExFat. Sdfat formatted even has a warning about that

Reformatted clean and empty - ExFat and still won't mount?

Then put in PC confirmed ExFat and added a file and repowered the T_4.1 - ALL GOOD now:
Code:
Initializing USB MSC drive...initialization failed!

Initializing USB MSC drive...initialization done.
System Volume Information/
  WPSettings.dat                                  12    13:01  September 28, 2021
  IndexerVolumeGuid                               76    13:16  September 28, 2021
AData64GB_ExFat.txt                               44    13:27  September 28, 2021
done!

And for sure the 256GB Samsung Flash with 32KB Sectors (?) is FAT32:
Samsun256Fat32.jpg
And T_4.1 can dir that drive - one mentioned above >> 184K files and 29K folders on FAT32
 
Yep - For some things Fat32 sort of sucks, at least with our implementations of Fat32, where the main code to query how much space is free (or used), has to read in all a lot of fat sectors and count bits to figure out the count.

It does not make use of the Information page that has a best guess stashed in it.
My Hack callback code in SDMTPClass.cpp does read it in... It may not work all the time... It does not get updated...

Need to figure out another way... Or at least Augment this. Would be best if built directly into SDFat code base, but...
 
Tim - you got me started thinking as well. Even though you had a 256GB USB flash formated at FAT32 it still should have worked. So I went ahead and formated a 128GB flash as FAT32 (you can't do it from Windows - used partition magic) to see what was going on.

Started with clean formatted drive no files except those system files that Windows adds.

Ran DataloggerUSB and timed how long it took from the time I asked for a file list to when it started printing. Well, it took almost 31 seconds before space used got calculated - the directory started printing right after that no delays. So image a larger USB how long it will take. ExFat is a different story so doesn't seem to suffer the same faith.

As Kurt said need to figure something else out.
 
Ran DataloggerUSB and timed how long it took from the time I asked for a file list to when it started printing. Well, it took almost 31 seconds before space used got calculated - the directory started printing right after that no delays. So image a larger USB how long it will take. ExFat is a different story so doesn't seem to suffer the same faith.
.

Is there a problem :D only 30+ seconds? luckily with current release TD, the option in SDFAT MAINTAIN_FREE_CLUSTER_COUNT is turned on by default for none AVR boards as with this turned off you will get the same 30 seconds on every call to the method...
With this option, the code simply does is sees if it has already done the long compute... If so returns cached value, else, it scans all of the FAT sectors and counts the bits... And every time calls are made the allocate or free sectors, it updates the count...

With the MTP integration stuff, I have hack in place for when remote location asks for the count of space free/used the code on Fat32 partition. Which relies on our pfslib currently in MSC code base,
for the PFsVolume support where we added int the partVol.getFSInfoSectorFreeClusterCount(); function to read the information sector for its stashed count stored in information sector.

Note: This hack/shortcut I believe is NOT in the code for the MSC (USB Host) plugged in drives.

Problem with this sector is that SDFat does not maintain this count... So probably reasonable if SD comes from some external source like PC/MAC/Windows... If this calls fails, the
code hack for FAT32 is to give back half full....

I was thinking of playing more with the MTP integration call back class for the SD card (and maybe MSC), that could update the information sector.. Would be nice if it would be done directly within SDFat's Fat32 support, but did not get a strong positive response to making changes in this area.

Thoughts are something along the line:
a) Read in Info sector count and do some simple checks like not zero and less than total, and setup our internal cached value with this, also remember it was a best guess...
b) have some background code, startup that maybe when idle it does the long reading of the FAT partition, and compute the real value... Lots of interesting things depending on how done, like if I read the first half and then other calls allocate/free sectors from that area, can I catch it and directly adjust count in progress or start over... Maybe we can do this each time, or maybe something triggers this... Like if I have a 256GB disk and the information sector says 200GB free and our code does update it... Do I really care if actually turns out we only have 198GB free?

Note: I might start playing with doing this in the MTP SD callback class, that mentioned above, that maybe in the newer ::loop callback that we are using now to detect in some cases when SD Card is plugged in. that this callback could for example try reading through the Fat Sectors and counting bits and when it completes it updates the information sector and it's cheat number...

Alternative to this is figure out how many times I need to cheat in order to make sure MTP starts up properly and then after let it fall through to let it then ask FS to get the true free (in this case 30 seconds)... And again at some point's we update the information sector...

c) If we could build it directly into Fat32 FS code, like mentioned in b) Could better integrate into FS. For example there is no callable function for me to tell Fat32 that use this as your current best guess count... If there was we might call that first time when we open disk and then not have to try to intercept calls...

Could have something like the File.close() method on files opened for write, detect if free count changed and update information sector. ...

Sorry maybe too much rambling here... hope some of this makes sense
 
KurtE said:
Is there a problem only 30+ seconds?.... Sorry maybe too much rambling here... hope some of this makes sense

Was poking into FAT32 spec and SDFat library last night before zzz's. And no easy solution from what I saw for FAT32 - guess that is why the 32GB limit for FAT32 even though you can create a FAT32 on large drives.

SDFat does have a few functions after it gets the sector count but does not write back to the SD card which guess makes sense - as you said not necessarily maintaind in FSINFO.
1. setfreeclustercount
2. updateFreeClusterCount
and somthing interesting that I just spotted
3. cacheFetchFat

this is all in FatPartition.h.

Right now the lib starts does
Code:
if (fatType() == 16 || fatType() == 32) {
    sector = m_fatStartSector;
    while (todo) {
      cache_t* pc = cacheFetchFat(sector++, FsCache::CACHE_FOR_READ);
      if (!pc) {
        DBG_FAIL_MACRO;
        goto fail;
      }
      n =  fatType() == 16 ? m_bytesPerSector/2 : m_bytesPerSector/4;
      if (todo < n) {
        n = todo;
      }
      if (fatType() == 16) {
        for (uint16_t i = 0; i < n; i++) {
          if (pc->fat16[i] == 0) {
            free++;
          }
        }
      } else {
        for (uint16_t i = 0; i < n; i++) {
          if (pc->fat32[i] == 0) {
            free++;
          }
        }
      }
      todo -= n;
    }
  } else {
    // invalid FAT type
    DBG_FAIL_MACRO;
    goto fail;
  }
  setFreeClusterCount(free);
where todo = lastclustercount+1.

If we don't need an exact number for large drives maybe instead of
Code:
n =  fatType() == 16 ? m_bytesPerSector/2 : m_bytesPerSector/4
we change to something else. what that something else ???? or after first time through use setFreeclusters in the FSINFO structure as yo said

Now this is rambling = not what you said.
 
Just by way of comparison a 32GB fat usb flash took about a 1 second to return the free space while a 128GB drive takes 30+ seconds.
 
SDFat does have a few functions after it gets the sector count but does not write back to the SD card which guess makes sense - as you said not necessarily maintaind in FSINFO.
1. setfreeclustercount
2. updateFreeClusterCount
and somthing interesting that I just spotted
3. cacheFetchFat

this is all in FatPartition.h.
Last time I checked these functions were all private, so could not call them from external things like our callback.
 
Yeah - just looked again and missed the "private" when scanning the file on Github but interesting thing is " m_freeClusterCount " doesn't look like its private so --- couldn't we add to our own stuff and maintain the FSINO. Would be alot easier if some of this could change in SDFat.
 
@Paul and all:
@mjs513 - let me know if I missed anything.

I thought I might give a quick update and let others know, the state of the different libraries and changes since the current TD Beta:

Many of the libraries and cores are the same, although there have been a few fixes since the beta 1:

Core: teensy4 (usb_mtp.h and usb_mpt.cpp) were updated, to fix the event code... Note: other changes have also been made to core, but unrelated... Although I running up to date code.

SD: Source code same as in beta
SDFat: Source Code same as in beta

LittleFS: Source code same as in beta

USBMSCFat (MSC): Changes have been made since the beta, last ones I believe were about two days ago: https://github.com/mjs513/UsbMscFat/tree/FS_Integration

MTP: As has been suggested, I made a new copy of the project: Which is now up at: https://github.com/KurtE/MTP_Teensy
The current stuff is now in the default branch: main
All of the source files (.h, .cpp and .ino) have been run through: clang-format -i
Which for example all Adafruit libraries now do.

So far on W10 we have had good luck working with SD, LittleFS, and MSC drives, with showing dates and times and the like.
I have tested so far on T4, T4.1 and T3.6. Lots more testing and fixing and unifying to go.

But having fun!

Kurt
 
Did a quick post #1 update adding:

Code:
[B][COLOR="#FF0000"]9/30/21 : p#135[/COLOR][/B] - status update >> [URL="https://forum.pjrc.com/threads/68139-Teensyduino-File-System-Integration-including-MTP-and-MSC?p=289869&viewfull=1#post289869'"][B]Teensyduino-File-System-Integration-including-MTP-and-MSC[/B][/URL]
 
Did a quick post #1 update adding:

Code:
[B][COLOR="#FF0000"]9/30/21 : p#135[/COLOR][/B] - status update >> [URL="https://forum.pjrc.com/threads/68139-Teensyduino-File-System-Integration-including-MTP-and-MSC?p=289869&viewfull=1#post289869'"][B]Teensyduino-File-System-Integration-including-MTP-and-MSC[/B][/URL]

Thanks, I meant to do that, but got sidetracked
 

Sounds great...

I just synced up everything on my Ubuntu machine and built mtp-test and it actually shows up three storages (PROGM, RAM, SDIO) Under Teensy MTP Disk.
Which is a lot better than what I saw before! :D

The one file did not show Modified field, but nice progress!

Edit: It also handled me plugging in the SD card into SDIO and was able to display the files...
 

Sounds good.

Right now experimenting running on T3.6 with our setup of current sources...
Note: I pushed up a change to MTP_Teensy for preserving dates and times that come over from host.

Now investigating a few issues.

a) Did format on SD card, saw debug of it formatting :D
Code:
100f 20 1 345:  20001 0
 MTPD::formatStore called post:0
Writing FAT ................................
Format Done
2001 20 3 345:  20001 0
1005 16 1 346:  20001
131073 1 name:SD_Card
131073 1 name:SD_Card
But files still there as far as MTP was concerned.
Tried sending refresh... Still files there...
But then rebooted and not there...

SO next to checkout the event code again...

Also copy files to storages on Teensy 3.x has issues with MTP not happy and timing out much easier.... I added stuff earlier to T4 to reduce that issue...
 

Unlike @KurtE not having much luck with the T3.6 or the T4.1. Thought I had everything synched up but going to go through everything again. Will update this post if I get it working

EDIT: Ok got it working now but am seeing the same thing as Kurt. Does the format but the files still show with the T3.6. If I power cycle the files are gone. Now for the T4.1

T4.1 using simple.ino works as well, at least its getting called. But still has the issue of files still showing and not seen as erased until power cycle.

Now to test with MTP_test - that will be in the next post
 
Last edited:
Would a 1.56-beta2 installer help?

I was imagining doing it several hours ago, but then got into the USB serial issue again, and now I'm having a lot of second thoughts about FS mediaPresent(). Was hoping to get both format() and mediaPresent() into SD.h before an installer, so hopefully all changes can be only needed in MTP and MSC.
 
Would a 1.56-beta2 installer help?

I was imagining doing it several hours ago, but then got into the USB serial issue again, and now I'm having a lot of second thoughts about FS mediaPresent(). Was hoping to get both format() and mediaPresent() into SD.h before an installer, so hopefully all changes can be only needed in MTP and MSC.

Seems to be almost working now - I was using MTP_Test and would not format, kept getting error message not supported. Switched to the simple.ino test sketch and it does say its formating but files remain which Kurt is trying to track down. So not don't think at this point a beta2 installer would help - think we got everything synced from the core at this point.

Interesting think is it does seem to work with a exFat formated SD Card (512GB).

At this point Kurt and I are pulling out our hair.
 
Seems to be almost working now - I was using MTP_Test and would not format, kept getting error message not supported. Switched to the simple.ino test sketch and it does say its formating but files remain which Kurt is trying to track down. So not don't think at this point a beta2 installer would help - think we got everything synced from the core at this point.

Interesting think is it does seem to work with a exFat formated SD Card (512GB).

At this point Kurt and I are pulling out our hair.

Right now testing on T3.6... and as I mentioned, I try a format, looks like it succeeds, then it looks like it is rebuilding the storage index and it shows all of the old files on the SD...
So thought maybe having open file on folder then format, then listing again it gets old contents...
SO did quick and dirty sketch:
Code:
// List files, format, list files
#include <SD.h>

// change this to match your SD shield or module;
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
// Wiz820+SD board: pin 4
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 & 4.1 on-board: BUILTIN_SDCARD
const int chipSelect = BUILTIN_SDCARD;

void setup()
{
  //Uncomment these lines for Teensy 3.x Audio Shield (Rev C)
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  File root = SD.open("/");

  printDirectory(root, 0);

  Serial.println("Press any key to reformat disk");
  while (Serial.read() == -1);
  while (Serial.read() != -1) ;
  SD.format(0,"*", Serial);

  Serial.println("\nNow try listing files again");
  while (Serial.read() == -1);
  while (Serial.read() != -1) ;
  printDirectory(root, 0);

  Serial.println("done!");
}

void loop()
{
  // nothing happens after setup finishes.
}

void printDirectory(File dir, int numSpaces) {
  while (true) {
    File entry = dir.openNextFile();
    if (! entry) {
      //Serial.println("** no more files **");
      break;
    }
    printSpaces(numSpaces);
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numSpaces + 2);
    } else {
      // files have sizes, directories do not
      unsigned int n = log10(entry.size());
      if (n > 10) n = 10;
      printSpaces(50 - numSpaces - strlen(entry.name()) - n);
      Serial.print("  ");
      Serial.print(entry.size(), DEC);
      DateTimeFields datetime;
      if (entry.getModifyTime(datetime)) {
        printSpaces(4);
        printTime(datetime);
      }
      Serial.println();
    }
    entry.close();
  }
}

void printSpaces(int num) {
  for (int i = 0; i < num; i++) {
    Serial.print(" ");
  }
}

void printTime(const DateTimeFields tm) {
  const char *months[12] = {
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  };
  if (tm.hour < 10) Serial.print('0');
  Serial.print(tm.hour);
  Serial.print(':');
  if (tm.min < 10) Serial.print('0');
  Serial.print(tm.min);
  Serial.print("  ");
  Serial.print(months[tm.mon]);
  Serial.print(" ");
  Serial.print(tm.mday);
  Serial.print(", ");
  Serial.print(tm.year + 1900);
}
But that ran fine:
Code:
Initializing SD card...initialization done.
System Volume Information/
  WPSettings.dat                                   12    10:12  October 5, 2021
  IndexerVolumeGuid                                76    10:12  October 5, 2021
DSC03359.JPG                                  2947914    08:17  March 22, 2010
IMG_0105.JPG                                  2750357    11:25  October 27, 2013
L1020581.psd                                  2580738    18:00  April 27, 2016
DSC03356.JPG                                  3355221    08:11  March 22, 2010
DSC03357.JPG                                  3343737    08:11  March 22, 2010
DSC03361.JPG                                  3223767    08:44  April 18, 2010
DSC03360.JPG                                  3161263    08:43  April 18, 2010
IMG_0107.JPG                                  2969229    11:32  October 27, 2013
Press any key to reformat disk
Writing FAT ................................
Format Done

Now try listing files again
done!
As for pulling hair out... Maybe not much.... Not much left to pull :D

So next up... Maybe it did not destroy the index list and is simply rereading it? ...
Now to add some more debug outputs.

Beta2 release? Maybe makes sense to debug a few more things. That is the few of us I think are already synced up to most everything, but if others want to join in, then we need to update the list of things that we have updated, like SD, SDFat, LittleFs, Core, ...
 
Just a quick update between other tasks.

I finally sorted out the issue with MTP_test and why it was failing using format. It seems that with all the changes it no longer likes the short cut of:
Code:
SDClass sdx[nsd];
using this it fails formating both the FAT32 card on the Audio shield and the builtin-card on the T4. Fix was simple, just have to specify SD directly in addfilesystem
Code:
            storage.addFilesystem(SD, sd_str[ii]);

Will push up the change in a bit.
 
Will check it out... Right now still pulling hair... As I mentioned in previous post, format runs, but files still show up...
Added more debug output to sketch slightly modified version of simpl... Could actually use simple...

Here is showing slightly edited... Removed a bunch of no helpful more ::OpenIndex messages...

Note: I copied in the more verbose MTP Message output code into T3.x version, makes it a lot easier for me to look through it. (Not uploaded yet)

Code:
131073 1 name:SD_Card
131073 1 name:SD_Card
19528 RESP:2001(RSP:OK)l: 16 T:20 : 20001
[COLOR="#FF0000"]28006 CMD: 100f(FORMAT_STORE)l: 20 T:21 : 20001 0
 MTPD::formatStore called post:0
Writing FAT ................................
Format Done[/COLOR]
MTPStorage::ResetIndex() called
After index test
MTPStorage::CloseIndex called
Index is closed
28328 RESP:2001(RSP:OK)l: 20 T:21 : 20001 0
28332 CMD: 1005(GET_STORAGE_INFO)l: 16 T:22 : 20001
131073 1 name:SD_Card
131073 1 name:SD_Card
28332 RESP:2001(RSP:OK)l: 16 T:22 : 20001
[COLOR="#FF0000"][COLOR="#FF0000"]28878 CMD: 1007(GET_OBJECT_HANDLES)l: 24 T:23 : 10001 0 ffffffff
*** MTPStorage::GenerateIndex called ***
    remove called: 0 /mtpindex.dat
MTPStorage::OpenIndex
Index is opened
0: 0 1 0 -1 0 0 /
MTPStorage::OpenIndex
1: 1 1 0 -1 0 0 /[COLOR="#FF0000"][/COLOR]
2: 2 1 0 -1 0 0 /[/COLOR][/COLOR]
** ScanDir called 0 0
  >> 3: 0 0 0 0 0 0 mtpindex.dat
** ScanDir called 0 0
** ScanDir called 0 0
28892 RESP:2001(RSP:OK)l: 24 T:23 : 10001 0 ffffffff
28892 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:24 : 3 dc02 (FORMAT)
28892 RESP:2001(RSP:OK)l: 20 T:24 : 3 dc02
28893 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:25 : 3 dc41 (PERSISTENT_UID)
28893 RESP:2001(RSP:OK)l: 20 T:25 : 3 dc41
28894 CMD: 1007(GET_OBJECT_HANDLES)l: 24 T:26 : 20001 0 ffffffff
** ScanDir called 1 1
 [COLOR="#FF0000"] >> 4: 1 0 0 1 0 8732 FS.h[/COLOR]
** ScanDir called 1 1
** ScanDir called 1 1
28905 RESP:2001(RSP:OK)l: 24 T:26 : 20001 0 ffffffff
28905 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:27 : 4 dc02 (FORMAT)
28905 RESP:2001(RSP:OK)l: 20 T:27 : 4 dc02
28906 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:28 : 4 dc41 (PERSISTENT_UID)
28906 RESP:2001(RSP:OK)l: 20 T:28 : 4 dc41
28908 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:29 : 4 dc03 (PROTECTION)
28908 RESP:2001(RSP:OK)l: 20 T:29 : 4 dc03
28909 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:2a : 4 dc04 (SIZE)
28911 RESP:2001(RSP:OK)l: 20 T:2a : 4 dc04
28912 CMD: 1008(GET_OBJECT_INFO)l: 16 T:2b : 4
28913 RESP:2001(RSP:OK)l: 16 T:2b : 4
28914 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:2c : 4 dc01 (STORAGE_ID)
28915 RESP:2001(RSP:OK)l: 20 T:2c : 4 dc01
28916 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:2d : 4 dc07 (OBJECT NAME)
28918 RESP:2001(RSP:OK)l: 20 T:2d : 4 dc07
28918 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:2e : 4 dc08 (CREATED)
Create (615c49ae)Date/time:20211005T124846
Create (615c49ae)Date/time:20211005T124846
28922 RESP:2001(RSP:OK)l: 20 T:2e : 4 dc08
28923 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:2f : 4 dc09 (MODIFIED)
Modify (6159df44)Date/time:20211003T165012
Modify (6159df44)Date/time:20211003T165012
28927 RESP:2001(RSP:OK)l: 20 T:2f : 4 dc09
28928 CMD: 9803(GET_OBJECT_PROP_VALUE)l: 20 T:30 : 4 dc44 (NAME)
28929 RESP:2001(RSP:OK)l: 20 T:30 : 4 dc44
Some of the Red lines are most interesting.
We do the format, Then MTP asks for object handles... We add our storages back into the start of new file
Then we call scandir which returns a File: fs.h
that was there...

Other sketch did not show this up. I tried quick hack to close file_ did not help. Wondering if we have SD or code that has cached contents? ...
 
Mike and Paul and others...

Now am able to reproduce files showing up without our MTP code after the new format runs.
Here is slightly modified version of code:
Code:
// List files, format, list files
#include <SD.h>

// change this to match your SD shield or module;
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
// Wiz820+SD board: pin 4
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 & 4.1 on-board: BUILTIN_SDCARD
const int chipSelect = BUILTIN_SDCARD;

void setup()
{
  //Uncomment these lines for Teensy 3.x Audio Shield (Rev C)
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  File root = SD.open("/");

  printDirectory(root, 0);
  root.close();

  Serial.println("Press any key to reformat disk");
  while (Serial.read() == -1);
  while (Serial.read() != -1) ;
  SD.format(0,'*', Serial);

  Serial.println("\nNow try listing files again");
//  while (Serial.read() == -1);
//  while (Serial.read() != -1) ;
  root = SD.open("/");
  printDirectory(root, 0);

  Serial.println("done!");
}

void loop()
{
  // nothing happens after setup finishes.
}

void printDirectory(File dir, int numSpaces) {
  while (true) {
    File entry = dir.openNextFile();
    if (! entry) {
      //Serial.println("** no more files **");
      break;
    }
    printSpaces(numSpaces);
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numSpaces + 2);
    } else {
      // files have sizes, directories do not
      unsigned int n = log10(entry.size());
      if (n > 10) n = 10;
      printSpaces(50 - numSpaces - strlen(entry.name()) - n);
      Serial.print("  ");
      Serial.print(entry.size(), DEC);
      DateTimeFields datetime;
      if (entry.getModifyTime(datetime)) {
        printSpaces(4);
        printTime(datetime);
      }
      Serial.println();
    }
    entry.close();
  }
}

void printSpaces(int num) {
  for (int i = 0; i < num; i++) {
    Serial.print(" ");
  }
}

void printTime(const DateTimeFields tm) {
  const char *months[12] = {
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  };
  if (tm.hour < 10) Serial.print('0');
  Serial.print(tm.hour);
  Serial.print(':');
  if (tm.min < 10) Serial.print('0');
  Serial.print(tm.min);
  Serial.print("  ");
  Serial.print(months[tm.mon]);
  Serial.print(" ");
  Serial.print(tm.mday);
  Serial.print(", ");
  Serial.print(tm.year + 1900);
}
Here is the output....
Code:
Initializing SD card...initialization done.
System Volume Information/
  WPSettings.dat                                   12    13:47  October 5, 2021
  IndexerVolumeGuid                                76    13:47  October 5, 2021
FS.h                                             8732    16:50  October 3, 2021
Press any key to reformat disk
Writing FAT ................................
Format Done

Now try listing files again
System Volume Information/
  WPSettings.dat                                   12    13:47  October 5, 2021
  IndexerVolumeGuid                                76    13:47  October 5, 2021
done!
Again I think somewhere has some data cached ... Differences from before, I did not pause waiting for keyboard before trying to get the data again. And I closed the root directory after listing and then reopened after the format...

Paul:
Your changes to SD library: Probably should add the new methods to keywords.txt
 
Hmm... maybe the SD library is caching enough to read the root folder again?

Will add the keywords.

Looks like reading the SD card's CID or CSD registers isn't as easy as I thought. Bill's code always reads them from the card for SPI, but with SDIO he reads them into memory at startup and calls to read them just return the bytes from RAM regardless of whether the hardware is present or removed. So I tried editing SdioCard readCID() to just read it from the card, but sadly it's not so simple. Turns out you can't just use any command at any moment in SDIO mode like you can with SPI mode. The card goes into different states and only certain commands work in each state (yes, I ended up diving into the SD card spec again...) which is probably why Bill decided to just read them once before transitioning to the state where reading & writing media is possible.

Still playing with media detection by SD card commands only. Looks like it might be possible (without a lot of mods to SdFat) with a combination of 2 different commands.
 
Back
Top