MTP file size limits.

I synced up the USBHost changes and I am still not seeing the USB drive show up in the MTP sketch I posted.

Please try with this program.

Code:
#include <SD.h>
#include <USBHost_t36.h>
#include <MTP_Teensy.h>

//#define CS_PIN 10
#define CS_PIN BUILTIN_SDCARD

USBHost myusb;
USBHub myhub(myusb);
USBDrive mydrive(myusb);
USBFilesystem mydisk(myusb);


void setup() {
  Serial.begin(9600);
  //while (!Serial) ;
  Serial.println("Begin");
  MTP.begin();
  SD.begin(CS_PIN);
  MTP.addFilesystem(SD, "SD Card");
  myusb.begin();
  MTP.addFilesystem(mydisk, "USB Disk");
}

void loop() {
  MTP.loop();
  myusb.Task();
  // do other things here...
  static elapsedMillis msec;
  if (msec > 2500) {
    msec = 0;
    static unsigned int count = 0;
    //Serial.printf("loop %u\n", count++);
  }
 
}
 
So unless I am missing something, your changes removed any code, that could detect that a new USB drive was inserted and enumerate to find any volumes we could add to the list of storages...

Perhaps you missed the code in MTPStorage::loop() ?


But as no one actually adds any volumes in... This {the mediaPresent function} would never be called.

It does indeed call FS::mediaPresent(), on line 1899. You can easily confirm by adding a Serial.print() within that function.
 
Here's a quick video demo. Hopefully this helps?

I do have 1 known bug to fix regarding SD card detection. It's in the demo starting around 1:26. (EDIT: bug fixed, see msg #80 for details)


Arduino sketch code used in this demo:
Code:
#include <SD.h>
#include <USBHost_t36.h>
#include <MTP_Teensy.h>

#define CS_PIN BUILTIN_SDCARD

USBHost myusb;
USBDrive mydrive(myusb);
USBFilesystem mydisk1(myusb);
USBFilesystem mydisk2(myusb);

void setup() {
  Serial.begin(9600);
  MTP.begin();
  SD.begin(CS_PIN);
  MTP.addFilesystem(SD, "SD Card");
  myusb.begin();
  MTP.addFilesystem(mydisk1, "USB Disk1");
  MTP.addFilesystem(mydisk2, "USB Disk2");
}

void loop() {
  MTP.loop();
  myusb.Task();
  // do other things here...
}
 
Last edited by a moderator:
Here's a quick video demo. Hopefully this helps?

I do have 1 known bug to fix regarding SD card detection. It's in the demo starting around 1:26.
Gave you sketch and my test sketch a try using your Micromod test board. Seems to be working. Not sure why its not working with the test sketch in the post that @KurtE posted. Might have an idea but won't be able to get to it until tomorrow.

EDIT: Tried it with the integrity sketch and works well with the SD Card removal and insertion - at least for the builtin sdcard:

Code:
Dump Storage list(3)
store:0 storage:10001 name:PgmIndx fs:2000a3e0 pn:(2)PROGRAM
store:1 storage:20001 name:BUILTIN fs:2000cc10 pn:(8)
store:2 storage:30001 name:PROGM fs:2000cad8 pn:(4-0)PROGRAM

Media removed "BUILTIN"(1)

Media inserted "BUILTIN"(1)

but as you can see the usb stick is still not recognized so more work to be done.
 
Last edited:
@mjs513 - Is the sketch that that you are using "Simplified Examples/Example_5_MTP_USB"? That one was the one that was not working for me due to a "#if 0"/#endif" in the "]void checkUSBDrives()" function. Here is the function:

Code:
void checkUSBDrives() {
  myusb.Task();

  // lets chec each of the drives.
  //bool drive_list_changed = false;

#if 0 <<<--------------------------------- Changeed to 1 and it works ------------------------------------------------

  for (uint16_t drive_index = 0; drive_index < (sizeof(drive_list)/sizeof(drive_list[0])); drive_index++) {
    USBDrive *pdrive = drive_list[drive_index];
    if (*pdrive) {
      if (!drive_previous_connected[drive_index] || !pdrive->filesystemsStarted()) {
        Serial.printf("\n === Drive index %d found ===\n", drive_index);
        pdrive->startFilesystems();
        Serial.printf("\nTry Partition list");
        pdrive->printPartionTable(Serial);
        //drive_list_changed = true;
        drive_previous_connected[drive_index] = true;
      }
    } else if (drive_previous_connected[drive_index]) {
      Serial.printf("\n === Drive index %d removed ===\n", drive_index);
      drive_previous_connected[drive_index] = false;
      //drive_list_changed = true;
    }
  }
  bool send_device_reset = false;
  for (uint8_t i = 0; i < CNT_USBFS; i++) {
    if (*filesystem_list[i]) {
      // So file system is valid do we have a MTP id for it?
      if ( (filesystem_list_store_ids[i] == 0xFFFFFFFFUL)) {
        Serial.printf("Found new Volume:%u\n", i); Serial.flush();
        // Lets see if we can get the volume label:
        char volName[20];
        if (filesystem_list[i]->mscfs.getVolumeLabel(volName, sizeof(volName)))
          snprintf(filesystem_list_display_name[i], sizeof(filesystem_list_display_name[i]), "MSC%d-%s", i, volName);
        else
          snprintf(filesystem_list_display_name[i], sizeof(filesystem_list_display_name[i]), "MSC%d", i);
        filesystem_list_store_ids[i] = MTP.addFilesystem(*filesystem_list[i], filesystem_list_display_name[i]);

        // Try to send store added. if > 0 it went through = 0 stores have not been enumerated
        if (MTP.send_StoreAddedEvent(filesystem_list_store_ids[i]) < 0) send_device_reset = true;
      } else if (filesystem_list[i]->changed()) {
        // Something with this file system changed.
        Serial.printf("File system changed volume: index=%d, store id:%x\n", i, filesystem_list_store_ids[i]);
        Serial.println("Show Partition list");
        filesystem_list[i]->device->printPartionTable(Serial);
        filesystem_list[i]->changed(false);
      }
    }
    // Or did volume go away?
    else if ((filesystem_list_store_ids[i] != 0xFFFFFFFFUL) && !*filesystem_list[i] ) {
      Serial.printf("Remove volume: index=%d, store id:%x\n", i, filesystem_list_store_ids[i]);
      if (MTP.send_StoreRemovedEvent(filesystem_list_store_ids[i]) < 0) send_device_reset = true;
      MTP.storage()->removeFilesystem(filesystem_list_store_ids[i]);
      // Try to send store added. if > 0 it went through = 0 stores have not been enumerated
      filesystem_list_store_ids[i] = 0xFFFFFFFFUL;
    }
  }
  if (send_device_reset) MTP.send_DeviceResetEvent();
#endif
}
Although it seems show two instances of a USB MTP drive...
 
Just tried it with a T41 and everything works as expected unless you plug a USB HUB in between the T41 and the USB drive then it fails to recognized the USB drive. The SD card is still recognized...

EDIT: Tried two different USB HUBs.
 
Something is definitely not right within USBHost_t36 with MSC media re-insertion with a hub. Quick test using the Storage > ListFiles example with printing the media status from loop(), to test without the extra complexity of MTP.

Code:
#include <USBHost_t36.h>

// Setup USBHost_t36 and as many HUB ports as needed.
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);

// Setup MSC for the number of USB Drives you are using. (Two for this example)
// Mutiple  USB drives can be used. Hot plugging is supported. There is a slight
// delay after a USB MSC device is plugged in. This is waiting for initialization
// but after it is initialized ther should be no delay.
USBDrive myDrive(myusb);
USBFilesystem firstPartition(myusb);

void setup()
{
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  // Start USBHost_t36, HUB(s) and USB devices.
  myusb.begin();

  Serial.print("\nWaiting for partition to...");

  while (!firstPartition) {
    myusb.Task();
  }
  Serial.println("initialization done.");

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

  printDirectory(root, 0);

  Serial.println("done!");
}

void loop()
{
  Serial.printf("mediaPresent = %s\n",
                (firstPartition.mediaPresent() ? "Yes" : "No"));
  delay(500);
}

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
      printSpaces(48 - numSpaces - strlen(entry.name()));
      Serial.print("  ");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

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

When I plug the MSC from the hub, loop starts printing "mediaPresent = No". But when I plug it back in, nothing. Loop no longer runs, nothing further prints.

1730948493710.png


Definitely a bug somewhere in USBHost_t36. Will try to dig into later tonight or tomorrow. But here's a quick update with test results, it anyone wants to try reproducing the problem or also looking into it.
 
Something is definitely not right within USBHost_t36 with MSC media re-insertion with a hub. Quick test using the Storage > ListFiles example with printing the media status from loop(), to test without the extra complexity of MTP.

Code:
#include <USBHost_t36.h>

// Setup USBHost_t36 and as many HUB ports as needed.
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);

// Setup MSC for the number of USB Drives you are using. (Two for this example)
// Mutiple  USB drives can be used. Hot plugging is supported. There is a slight
// delay after a USB MSC device is plugged in. This is waiting for initialization
// but after it is initialized ther should be no delay.
USBDrive myDrive(myusb);
USBFilesystem firstPartition(myusb);

void setup()
{
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  // Start USBHost_t36, HUB(s) and USB devices.
  myusb.begin();

  Serial.print("\nWaiting for partition to...");

  while (!firstPartition) {
    myusb.Task();
  }
  Serial.println("initialization done.");

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

  printDirectory(root, 0);

  Serial.println("done!");
}

void loop()
{
  Serial.printf("mediaPresent = %s\n",
                (firstPartition.mediaPresent() ? "Yes" : "No"));
  delay(500);
}

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
      printSpaces(48 - numSpaces - strlen(entry.name()));
      Serial.print("  ");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

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

When I plug the MSC from the hub, loop starts printing "mediaPresent = No". But when I plug it back in, nothing. Loop no longer runs, nothing further prints.

View attachment 36236

Definitely a bug somewhere in USBHost_t36. Will try to dig into later tonight or tomorrow. But here's a quick update with test results, it anyone wants to try reproducing the problem or also looking into it.
Will probably be tomorrow for me to look at it. Been a while since I looked at it...
 
@mjs513 - Is the sketch that that you are using "Simplified Examples/Example_5_MTP_USB"? That one was the one that was not working for me due to a "#if 0"/#endif" in the "]void checkUSBDrives()" function. Here is the function:
Just did the same thing with the MTp_test_integrityv2 sketch and indeed it worked as well
inte
1730981159150.png

however if you remove and replace a couple of times the usb
1730981318369.png


a couple times later
1730981356527.png


You notice if you pull out the usv stick you loose the sd card and wind up with sever more instances

have a feeling I know why but have to go to airport to pick up wife
 
Something is definitely not right within USBHost_t36 with MSC media re-insertion with a hub. Quick test using the Storage > ListFiles example with printing the media status from loop(), to test without the extra complexity of MTP.

Code:
#include <USBHost_t36.h>

// Setup USBHost_t36 and as many HUB ports as needed.
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);

// Setup MSC for the number of USB Drives you are using. (Two for this example)
// Mutiple  USB drives can be used. Hot plugging is supported. There is a slight
// delay after a USB MSC device is plugged in. This is waiting for initialization
// but after it is initialized ther should be no delay.
USBDrive myDrive(myusb);
USBFilesystem firstPartition(myusb);

void setup()
{
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  // Start USBHost_t36, HUB(s) and USB devices.
  myusb.begin();

  Serial.print("\nWaiting for partition to...");

  while (!firstPartition) {
    myusb.Task();
  }
  Serial.println("initialization done.");

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

  printDirectory(root, 0);

  Serial.println("done!");
}

void loop()
{
  Serial.printf("mediaPresent = %s\n",
                (firstPartition.mediaPresent() ? "Yes" : "No"));
  delay(500);
}

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
      printSpaces(48 - numSpaces - strlen(entry.name()));
      Serial.print("  ");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

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

When I plug the MSC from the hub, loop starts printing "mediaPresent = No". But when I plug it back in, nothing. Loop no longer runs, nothing further prints.

View attachment 36236

Definitely a bug somewhere in USBHost_t36. Will try to dig into later tonight or tomorrow. But here's a quick update with test results, it anyone wants to try reproducing the problem or also looking into it.
@Paul - With your last test sketch I added:
Code:
void loop()
{
 
  myusb.Task(); <<<---------- Added ---------------

  Serial.printf("mediaPresent = %s\n",
                (firstPartition.mediaPresent() ? "Yes" : "No"));
  delay(500);
}
Now it works. But in your first test sketch you were calling "myusb.Task();" in "loop()" so for some reason it's still not recognizing the media change in MTP_Teensy with a hub inserted...
 
Opps, I did indeed forget myusb.Task();

But that's not my only silly mistake I made yesterday! MSC wasn't working with a USB hub in the code on msg #53 because I didn't have a USBHub instance.

MSC media change seems to be working fine with the 2 USB drives and a 4 port hub using this program:

Code:
#include <SD.h>
#include <USBHost_t36.h>
#include <MTP_Teensy.h>

#define CS_PIN BUILTIN_SDCARD

USBHost myusb;
USBHub hub1(myusb);
USBDrive mydrive1(myusb);
USBDrive mydrive2(myusb);
USBFilesystem mydisk1(myusb);
USBFilesystem mydisk2(myusb);

void setup() {
  Serial.begin(9600);
  MTP.begin();
  SD.begin(CS_PIN);
  MTP.addFilesystem(SD, "SD Card");
  myusb.begin();
  MTP.addFilesystem(mydisk1, "USB Disk1");
  MTP.addFilesystem(mydisk2, "USB Disk2");
}

void loop() {
  MTP.loop();
  myusb.Task();
  // do other things here...
  static elapsedMillis msec;
  if (msec > 500) {
    msec = 0;
    Serial.printf("mediaPresent = %s - %s\n",
                  (mydisk1.mediaPresent() ? "Yes" : "No"),
                  (mydisk2.mediaPresent() ? "Yes" : "No"));
  }
}

1730989764021.png


FWIW, in this test I'm running the latest MTP_Teensy with a couple recent commits, but those probably would not have affected media detection.
 
I'm curious to hear.
In the previous version of MTP/USBhost just doing a myusb.Task() added the the filesystem for each drive automatically (its been awhile) . In the sketch that @KurtE posted even though we are calling myusb.Task() in the loop via checkMSCchanges it is not adding the filesystem for each drive. By changing the #if 0 to #if 1 it is now doing the calls to addfilesystem. But haven't figured out why its adding 2 for each drive or why it looses builtin sdcard on drive removal.

been playing with it but looks like i may have to go into your changes to figure it out.
 
I've been looking over mtp-test-integrityV2. Committed a copy on github.

There's a lot to unpack here.

First, ending up with duplicate stores probably means we do have an issue to fix. My gut feeling it is may be just a simple matter of MTP.addFilesystem() not checking whether a particular filesystem is already added. I still need to investigate.

The mtp-test-integrityV2 storage_configure() function which called MTP.addFilesystem() for all the others is not adding MSC drives. It really needs to add those too!

The checkMSCChanges() function has "#if 0" at line 240. If this is edited to 1, lots of old code gets added. This checkMSCChanges() code absolutely should not be used, since MTP.loop() does the detection of media insertion and removal for all FS types.

Long-term, these APIs checkMSCChanges() tries to use within MTP and USBHost_t36 will either become private or be completely removed. So will a lot of other stuff that's currently public.
 
I've updated mtp-test-integrityV2 with this commit. Please give this version a try. Files also attached to this message.

Here's a screenshot of it running with my Windows 11 test machine.

sc.png
 

Attachments

  • mtp-test-integrityV2.zip
    11 KB · Views: 14
The checkMSCChanges() function has "#if 0" at line 240. If this is edited to 1, lots of old code gets added. This checkMSCChanges() code absolutely should not be used, since MTP.loop() does the detection of media insertion and removal for all FS types.
I agree should not have too uncomment the code. And yes its not calling MTP.addFilesystem() since in previous branch it was handled automatically and used the volume names if available.

I just went back to @KurtE's large-file branch and it already correctly connects and disconnects usb drives and storage class handles the swap:
Code:
Dump Storage list(9)
store:0 storage:10001 name:PgmIndx fs:2000b40c pn:(2)PROGRAM
store:1 storage:20001 name:BUILTIN fs:2000dc3c pn:(8)
store:2 storage:30001 name:PROGM fs:2000db04 pn:(4-0)PROGRAM
store:3 storage:40001 name:(null) fs:0 pn:(8)
store:4 storage:50001 name:(null) fs:0 pn:(8)
store:5 storage:60001 name:MSC2-exFAT0 fs:2000bf14 pn:(8)
store:6 storage:70001 name:MSC3- fs:2000c3bc pn:(8)
store:7 storage:80001 name:MSC0 fs:2000b5c4 pn:(8)
store:8 storage:90001 name:MSC1-Data fs:2000ba6c pn:(8)

The null names shows that those devices are no longer available since they added. My current setup
1731011161443.png

My gut feeling it is may be just a simple matter of MTP.addFilesystem() not checking whether a particular filesystem is already added. I still need to investigate.
I agree.

Long-term, these APIs checkMSCChanges() tries to use within MTP and USBHost_t36 will either become private or be completely removed. So will a lot of other stuff that's currently public.
Well checkMSCChanges only really uses myusb.Task() - code was only left in for posterity and changed to #if 1 at @wwatson suggestion since it worked in that config

Screen shot in win 11:
1731011434287.png


Please note that in its the large-file branch supports multiple volumes on the same drive.
 
I spent several minutes plugging and unplugging combinations of these 4 USB sticks and 2 SD cards. So far the updated mtp-test-integrityV2 always detects them properly.

Please give the updated mtp-test-integrityV2 a try.

1731011754419.png
 
Sorry Paul meant to say was going to give it a try next but have to synch up with your branch and usbhost - next up but getting called away for a few minutes
 
Ok back at it. See you added this to address addfilesystem for msc:
Code:
  for (int i=0; i < nfs_usb; i++) {
    snprintf(filesystem_list_display_name[i], 20, "USB Disk %d", i + 1);
    MTP.addFilesystem(*usb_filesystem_list[i], filesystem_list_display_name[i]);
  }

On startup - only showing 2 of 3 drives:
1731012603516.png


And if I look at the storage list:
Code:
Dump Storage list(11)
store:0 storage:10001 name:PgmIndx fs:2000a480 pn:(2)PROGRAM
store:1 storage:20001 name:BUILTIN fs:2000ccb0 pn:(8)
store:2 storage:30001 name:PROGM fs:2000cb78 pn:(4-0)PROGRAM
store:3 storage:40001 name:USB Disk 1 fs:2000a638 pn:(8)
store:4 storage:50001 name:USB Disk 2 fs:2000aae0 pn:(8)
store:5 storage:60001 name:USB Disk 3 fs:2000af88 pn:(8)
store:6 storage:70001 name:USB Disk 4 fs:2000b430 pn:(8)
store:7 storage:80001 name:USB Disk 5 fs:2000b8d8 pn:(8)
store:8 storage:90001 name:USB Disk 6 fs:2000bd80 pn:(8)
store:9 storage:a0001 name:USB Disk 7 fs:2000c228 pn:(8)
store:10 storage:b0001 name:USB Disk 8 fs:2000c6d0 pn:(8)
shows filesystems for all 8 disks.

Looks like its only picking up the drive with 2 volumes.

Now if I restart the Teensy without the USB Stick with 2 volumes it works:
1731012912904.png

and I can remove/insert and it picks up the changes,

Note if I try to insert the drive with 2 volumes it does not pick it up.

Probably other things will need tweaking as we go.
 
The mtp-test-integrityV2 storage_configure() function which called MTP.addFilesystem() for all the others is not adding MSC drives. It really needs to add those too!

The checkMSCChanges() function has "#if 0" at line 240. If this is edited to 1, lots of old code gets added. This checkMSCChanges() code absolutely should not be used, since MTP.loop() does the detection of media insertion and removal for all FS types.

Long-term, these APIs checkMSCChanges() tries to use within MTP and USBHost_t36 will either become private or be completely removed. So will a lot of other stuff that's currently public.
Looks like you are having fun!

Maybe at this point, it makes sense for you to create your own github project or migrated portions of it over to core libraries. At which point I would probably make this private or archive it, with a top-level Readme that points everyone to your official version.
 
@PaulStoffregen

Just gave your latest changes a test but added the original memboard with 2 flash + 2 nand chips a long with the USB hub plus sd card. Looks like it lost the USB sticks on the hub (using the non-partitioned ones)
1731015290221.png


Same thing if I don't use a hub.
 
Quick update just tested with PSRAM enabled on a T4.1.
Code:
Dump Storage list(13)
store:0 storage:10001 name:PgmIndx fs:2000a494 pn:(2)PROGRAM
store:1 storage:20001 name:BUILTIN fs:2000ce5c pn:(8)
store:2 storage:30001 name:RAM0 fs:2000cc58 pn:(3-0)EXTMEM
store:3 storage:40001 name:RAM1 fs:2000cd24 pn:(3-1)EXTMEM
store:4 storage:50001 name:PROGM fs:2000cb8c pn:(4-0)PROGRAM
store:5 storage:60001 name:USB Disk 1 fs:2000a64c pn:(8)
store:6 storage:70001 name:USB Disk 2 fs:2000aaf4 pn:(8)
store:7 storage:80001 name:USB Disk 3 fs:2000af9c pn:(8)
store:8 storage:90001 name:USB Disk 4 fs:2000b444 pn:(8)
store:9 storage:a0001 name:USB Disk 5 fs:2000b8ec pn:(8)
store:10 storage:b0001 name:USB Disk 6 fs:2000bd94 pn:(8)
store:11 storage:c0001 name:USB Disk 7 fs:2000c23c pn:(8)
store:12 storage:d0001 name:USB Disk 8 fs:2000c6e4 pn:(8)

plugged in a usb stick and did not register.

Edit: if PSRAM not enabled is only seems to register my smaller usb drives. 2GB, 8gb. Its not registering my 128gb drive.

Trying PSRAM with the smaller drives still not registering the drive
 
Last edited:
Back
Top