MTP Responder Contribution

@ WMXZ
https://github.com/WMXZ-EU/MTP_t4
Missing preprocessor directives for Teensy 3.0/3.1/3.2/3.5 in MTP.h and MTP.cpp files.

In MTP.cpp: about LINE #519 #if defined(__MK66FX1M0__)
Replace with: #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

in MTP.h: about LINE #61 #if defined(__MK66FX1M0__)
Replace with: #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

This is of course not tested on Teensy 3.0/3.1/3.2/3.5 but no compilation error.
 
@ WMXZ
https://github.com/WMXZ-EU/MTP_t4
Missing preprocessor directives for Teensy 3.0/3.1/3.2/3.5 in MTP.h and MTP.cpp files.

In MTP.cpp: about LINE #519 #if defined(__MK66FX1M0__)
Replace with: #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

in MTP.h: about LINE #61 #if defined(__MK66FX1M0__)
Replace with: #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

This is of course not tested on Teensy 3.0/3.1/3.2/3.5 but no compilation error.

I guess, you are right.
Updated the github files
 
I'll be trying this out today--installing the TD 1.54 Beta #4 seems to break my earlier MTP responder.

Regarding the T4.1 implementation is the following still true:
// MTP object handles should not change or be re-used during a session.
// This would be easy if we could just have a list of all files in memory.
// Since our RAM is limited, we'll keep the index in a file instead.
void MTPStorage_SD::GenerateIndex()

An index record occupies 78 bytes. If your micro SD Card has 1000 files that's only 78KB for the index. That's about 15% of the DMAMEM or 8% of the total memory. Most of us probably don't put 1000 files on a micro SD. One to two hundred files is more likely. I'll have to look over the storage code to see how much simpler it would be if the index was in DMAMEM.
 
While playing around with the MTP responder today I think I've found a way to notify a connected PC that the Teensy directory needs to be updated.\

Code:
void CMRB(void){
  
  LEDON
  usb_init();  // shuts down USB if already started, then restarts
  delay(200);
  Serial.begin(9600);
  delay(200);
  LEDOFF
  //StartMTP();
  usb_mtp_configure();
  if (!Storage_init(&SD.sdfs)) {
    Serial.println("Could not initialize MTP Storage!");
  }
  Serial.println("USB disconnected and reconnected to force MTP update");
}

This rather brute force method does avoid the mechanical wear and tear that comes with unplugging and replugging the USB cable. The usb_init() call shuts down the USB link if it is already open, then restarts the USB. The PC will notice that, just like a hardware disconnect. You then re-open Serial and restart the MTP responder. Note that my Storage_init() function has been modified to accept a pointer to an existing file system so that the MTP responder doesn't have to create a new file system at each initialization.


Code:
//  Changed Storage_init to accept pointer to initialized SdFs file system
bool Storage_init(SdFs *sptr) {
#if DO_DEBUG>0
  Serial.println("Using SdFs");
#endif
#if USE_SDIO==0
  SPI.setMOSI(SD_MOSI);
  SPI.setMISO(SD_MISO);
  SPI.setSCK(SD_SCK);
#endif
  if (sptr == NULL) {// If NULL pointer  initialize FS
    if (!sd.begin(SD_CONFIG)) {
      return false;
      //sd.errorHalt("sd.begin failed");
    } else {
      sdptr = &sd;
      FsDateTime::callback = dateTime;
      return true;
    }
  } else {// we received a pointer to an intialized SD file system
      sdptr = sptr;
      return true;
  }

  // Set Time callback already done when File system initialized
  
}

You will have to reconnect your Serial port in your terminal program or restart the Serial Monitor. The MTP responder restarts automatically at the PC end.
 
I updated the MTP_t4 responder to allow access to multiple disks.

Usage has changed a little bit, as configuration is now done in main sketch
See mtp_test and mtp_logger for examples on usage


@mborgerson: to refresh mtp after logging to disk on Windows , best is to use Device manager ->Portable Devices -> Teensy -> Disable Device followed by an Enable device
IMO, this is equivalent to Linux unmount - mount sequence
 
@WMXZ
Was playing with MPT Responder (SD Card) to test rename functionality because I was getting some strange results with MTP rename. Specially it lets me rename one file without a problem but then if I go to rename a second file it looses the file name completely and the icon changes to a window icon with what looks like a drive icon? Is this a know issue.
 
@WMXZ
Was playing with MPT Responder (SD Card) to test rename functionality because I was getting some strange results with MTP rename. Specially it lets me rename one file without a problem but then if I go to rename a second file it looses the file name completely and the icon changes to a window icon with what looks like a drive icon? Is this a know issue.

Honestly, I did not test (again) rename, only copy to and from a card. Will have a look.
Obviously, renaming from one device to another is not tested either, maybe PC will fetch and store, something to test.
 
@mjs513, It turns out that sd.rename is not working as expected (returns false). Have to do some debugging
 
@mjs513, It turns out that sd.rename is not working as expected (returns false). Have to do some debugging

you might want to check what readstring returns in the setObjectPropValue functions. For my and SPIFlash seems filename returns the name of the file I want to change, the second time though it appears to be null?
 
OK,
@mjs513, was busy last two days debugging the code. Was a little bit intensive.
There was nothing wrong with sd.rename
but found that reading commands from PC got corrupted.
Also managing index file seemed to be corrupting.

At the moment I got rename working multiple times and move (within single storage seems also to work)
I updated the github, but I expect some strange actions to screw up.
 
OK,
@mjs513, was busy last two days debugging the code. Was a little bit intensive.
There was nothing wrong with sd.rename
but found that reading commands from PC got corrupted.
Also managing index file seemed to be corrupting.

At the moment I got rename working multiple times and move (within single storage seems also to work)
I updated the github, but I expect some strange actions to screw up.

That was kind of my conclusion this morning. Like you was trying to track down the issue yesterday and this morning until I figured out it wasn't getting the name from the PC. This morning I even extracted the code from MTP can put it into a sketch and on the MTP side seemed to be working. But just did that as a quick test.

I'll check out the changes
 
Unfortunately, I have to report a problem (win10 T4.1)
If I copy a sequence of files from a directory to top-level directory using CTL-X and CTL-V and try to copy multiple files back again, system blocks (no USB commands from PC are shown)
First copy works (verified)
Work around: if MTP window blocks (on file move) use device manager to disable and enable Teensy portable device.
 
Unfortunately, I have to report a problem (win10 T4.1)
If I copy a sequence of files from a directory to top-level directory using CTL-X and CTL-V and try to copy multiple files back again, system blocks (no USB commands from PC are shown)
First copy works (verified)
Work around: if MTP window blocks (on file move) use device manager to disable and enable Teensy portable device.

Considering everything else I personally don't see it as a too big of a problem :)

BTW: Just got it working with LittleFS_SPIFLASH to access multiple SPI Flash chips as you do with the SD Card. Great work on the MTP Library. PS Shouldn't be any conflict with current MTP library either. Have more work to do though :)
 
Considering everything else I personally don't see it as a too big of a problem :)
Somehow I screwed up the logic. (moving to root corrupted the object list)
I think I got it now working using an easier logic (added in scr code).
So far moving between different uSD cards is not supported, as I had no time testing it.
Github updated.
 
Last edited:
Somehow I screwed up the logic. (moving to root corrupted the object list)
I think I got it now working using an easier logic.
So far moving between different uSD cards is not supported, as I had no time testing it.
Github updated.

Cool - now I have to go and update my version to match what you have. Fixed my one problem as well and now seems to working as it should - at least when I get your update incorporated. Found out about moving files between different flash chips this morning - so at least you confirmed that issue. Was actually pretty neat to see both chips show up. You also resolved the issue with the device names nicely :)
 
@mjs513,
I added code to move files cross sd cards.
I seems to work with single files, but not with multiple files (in the latter case the is most likely some issues with the MTP protocol)
When copying multiple files cross sd cards, the first one is copied and the the MTP communication stops
 
@mjs513,
I added code to move files cross sd cards.
I seems to work with single files, but not with multiple files (in the latter case the is most likely some issues with the MTP protocol)
When copying multiple files cross sd cards, the first one is copied and the the MTP communication stops

Curious did you test moving one at time. Does it work with copying one and then another - not a show stopper for me. So far with what I am working on in the LittleFS thread got it working with your new stuff as of yesterday anyway. So you can now use multiple SPIFlash chips.. Have to say real nice job on how you have it set up.

Right now running into an issue explicit statement for setting storage. Guess ultimate goal is to say use more that one storage medium at a time. But if I take your suggestion and have separate MTP classes for each I start getting an error like
Code:
D:\Users\Merli\Documents\Arduino\libraries\MTP_t4_littlefs\src/MTP_RAM.h:47:42: error: expected ')' before '*' token
   explicit MTPD_RAM(MTPStorageInterface2 *storage2;) : storage2_(storage2) {}
if I try and say SPIFlash and RAMdisk at the same time. Individually it works. Any thoughts - have no clue about explicit statements.
 
Curious did you test moving one at time. Does it work with copying one and then another - not a show stopper for me.

Yes I did one at a time and it worked, but marking multiple files and then a doing a move failed.
Anyhow, moving files between storages is not the objective of my application. Will see how libmtp does it (unfortunately is not easy to revengineer, and it seems to code for initiator?, Will now look into viveris code)

Edit: Viveris does not support moveObject, so no working example
 
Last edited:
Yes I did one at a time and it worked, but marking multiple files and then a doing a move failed.
Anyhow, moving files between storages is not the objective of my application. Will see how libmtp does it (unfortunately is not easy to revengineer)

To be honest wasn't looking for you to do anything more was just curious since I don't really have a setup using multiple SD cards right now to test.
 
To be honest wasn't looking for you to do anything more was just curious since I don't really have a setup using multiple SD cards right now to test.

At the mean time I was moving the "sd_XXXX" defines into a own base class, which could be useful for porting to other devices.
Maybe one could control the devices by real or virtual CS numbers 0-253 SPI, 254 SDIO, 512 to QSPI, 1024 to RAM and all controlled in new Base class (only a thought)
 
@WMXZ
Good idea about moving all the defines into a base class - was thinking about it but low on the list. :)

The one challenge with the virtual CS number is that the 3 storage areas SPI, RAM and QSPI all have the different begin's:
Code:
SPIFlash:  begin(CS#, SPI Port)
RAM:   begin(buffer, sizeof(buffer)
QSPI:  begin()
That's why it was nice when you moved over to the configure in the sketch. Other thing is all three have there own class to call in the constructor.

Right now just can't see a way to say get SD MTP working at the same time as SPI for example.
 
@WMXZ
Just downloaded the latest update for MTP Responder using the Builtin_sdcard and a card reader on pin 4. Its failing!

Builtin_sdcard works if thats the only thing being accessed. If I set it up so only trying the SD card reader it fails - No Teensy shows up in the windows explorer. Only shows when I use Builtin_Sdcard.

Not sure whats going on now. This is the first time I tried multiple SD Cards. Both cards are good, tried each via SDIO. SD Card hook up right since I tested with SD cardinfo and listfiles just in case.
 
@mjs513
OK, for multiple cards you have to do two things in main program (*.ino)
- Making sure SPI port definitions are correct (the values in MTP_test are for Teensy 4.1, (added a note))
- changing the constants cs and sd_str
It should work, as I'm doing test right now
BTW, I added LittleFS_RAM on my device list and it seems to work

Edit: Just checked it with only a single SPI disk, and it worked
Edit: It is useful also to check the SPI speed
 
Last edited:
Back
Top