MTP Responder Contribution

The way I did it may be done better, but I was struggling with
Code:
void MTPStorage_SD::OpenIndex()
{ if(index_) return; // only once

index_.open((char*)"mtpindex.dat", FILE_WRITE);
….
}
if index_ is a file structure, how can it be zero, so that open is called?

Buried in the code for the base FSFile type is the following:
Code:
 /** The parenthesis operator.
    *
    * \return true if a file is open.
    */

operator bool() {return isOpen();}
That says that when you do a Boolean operation on an FsFile object, the result is true if the file is open.
In essence, it says "If the file is already open, don't try to open it again"

The opposite logic is used in MTP.ResetIndex:

Code:
void MTPStorage_SD::ResetIndex() {
  if (!index_) return;
Here the Boolean test returns with no action if the index file is NOt open, return with no action.

There's a warning in the Storage:
MTP object handles should not change or be re-used during a session.

So it appears that if you modify the index your new values may disagree with those in the
PC and chaos will ensue!

I wonder if there's a way to tell the PC to close the MTP session, then open a new session, at which time the Teensy would rebuild the index.
 
I wonder if there's a way to tell the PC to close the MTP session, then open a new session, at which time the Teensy would rebuild the index.

OK for Boolean comment.

The only way for MTP responder to tell PC to do something, is to issue an event.
Unfortunately, all my attempts to do that, failed. I could not find any information what MTP initiator can be interrogated about their capability.
 
This afternoon I did some tests in a common data logger configuration:

* Logger is powered by an external power supply.
* The trace on the bottom of the Teensy that connects USB 5V to VIN is cut.

When the USB cable is connected, USB Serial starts up without problems.

The MTP responder does not start automatically.

I added a function that is called in Setup():
Code:
void StartMTP(void){
  Serial.println("Starting MTP Responder");
  usb_mtp_configure();
  if(!Storage_init(fsptr)) {
    Serial.println("Could not initialize MTP Storage!"); 
    fastBlink();
   } else MTPLoopOK = true;
}

This function uses my modified Storage_Init function where I pass a pointer to the data logger's initialized SD File system. As a result, I don't generate a new file system with each call to Storate_Init().

If you unplug the USB cable while the Logger program is running off external power, the logger continues to run, but the PC notices that the USB connection to the MTP responder is cut. The Teensy device disappears from the Fle Explorer on Win10.

If you later plug in the USB cable, there are various beeps, and you can reconnect to USB Serial. However, the Teensy removable device does not automatically appear in the 'this PC' window in Explorer. To make it appear, you have to call the following function:

Code:
void StartMTP(void){
  Serial.println("Starting MTP Responder");
  usb_mtp_configure();
  if(!Storage_init(fsptr)) {
    Serial.println("Could not initialize MTP Storage!"); 
    fastBlink();
   } else MTPLoopOK = true;
}

The MTPLoopOK variable is used to shut down calls to mtdp.loop() when loggning. It allows the calls when not logging and the calls happen several thousand times per second. Repeated calls to Storage_Init () and usb_mtp__configure() don'tseem to cause problems.

When this function StartMTP() is called from the data logger command handler, the MTP responder seems to rebuild the index file and files appear in the Teensy/sdcard display on the PC.

I spent some time looking for a software method to make the PC think the USB had been disconnected--without much success on the T4.1. Physically pulling out the USB connector is a valid way to handle things for a lot of the logger systems I've worked with. For those systems, you use the USB connection to set up the logger. When you are ready to deploy, you pull the USB connector and replace it with a waterproof dummy plug. At some predefined time in the future, the logger starts recording.
 
Physically pulling out the USB connector is a valid way to handle things for a lot of the logger systems I've worked with. For those systems, you use the USB connection to set up the logger. When you are ready to deploy, you pull the USB connector and replace it with a waterproof dummy plug. At some predefined time in the future, the logger starts recording.
Unfortunately, in my applications, I cannot pull the USB plug, so I must stick to unmount/mount method.
 
Hi everyone

I am trying to get this to work on T4.1, Ubuntu 18.04, IDE 1.8.12, td 1.52 and need some help please.

I have the latest MTP-t4, USB2 and sdFat libraries and have modified Storage.h, sdFatConfig.h, usb.c, usb_desc.h, boards.txt as per the instructions. A couple of extra MTP_EVENT_INTERVAL lines were needed in usb_desc.h to get mtp-test to compile:

Code:
  #define MTP_EVENT_SIZE        16
  #define MTP_EVENT_INTERVAL    1

// Dean 16/06/2020
[COLOR="#FF0000"]  #define MTP_EVENT_INTERVAL_12	10	// 10 = 10 ms
  #define MTP_EVENT_INTERVAL_480 7	// 7 = 8 ms
[/COLOR]  
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK
  #define ENDPOINT5_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT  // ????

So, mtp-test compiles and uploads and 'Teensy MTP Disk/Serial' appears in the file manager (Nautilus). The following appears in the serial monitor:

Code:
MTP test
1002 16 1 0: 1 0 0
1001 12 1 1: 1 0 0
1004 12 1 2: 1 0 0
1007 24 1 3: ffffffff 0 ffffffff
1007 24 1 4: 1 0 ffffffff
1004 12 1 5: 1 0 ffffffff
1005 16 1 6: 1 0 ffffffff
1003 12 1 7: 1 0 ffffffff
1002 16 1 0: 1 0 ffffffff
1001 12 1 1: 1 0 ffffffff
1004 12 1 2: 1 0 ffffffff
1007 24 1 3: ffffffff 0 ffffffff
1007 24 1 4: 1 0 ffffffff
1004 12 1 5: 1 0 ffffffff
1005 16 1 6: 1 0 ffffffff
1004 12 1 7: 1 0 ffffffff
1005 16 1 8: 1 0 ffffffff
loop
loop

I click on the Teensy, it opens and the files are visible with correct sizes, types, etc. However, copying to PC, opening, deleting, etc. does not work: "Unexpected error: Error getting file: -7: I/O problem". I can copy 1 file from PC to Teensy, but then it breaks.

I have tried refomatting the card, different ports, a shorter cable :eek: (#179) and as many settings changes as I can find. No joy.

Any ideas?

Also, would it be possible to make the Teensy drive appear when it is plugged in? Thanks.
 
Updated the usb_desc.h to include the missing defines

Not sure why it does not work with Nautilus (I'm not using Linux)
The printout suggests, that the MTP server is not working properly:
It repeats the same set command twice including sequence number (fourth number) starting from 0.
It could be Nautilus is repeating same printout twice.
I know MTP responder is working under Nautilus, but I cannot investigate.
 
Thank you. That gives me somewhere to start investigating.

Here is some more serial output when mtp-test is run:
Code:
MTP test
[COLOR="#FF0000"]1002 16 1 0: 1 0 0
1001 12 1 1: 1 0 0
1004 12 1 2: 1 0 0
1007 24 1 3: ffffffff 0 ffffffff
1007 24 1 4: 1 0 ffffffff
1004 12 1 5: 1 0 ffffffff
1005 16 1 6: 1 0 ffffffff
1003 12 1 7: 1 0 ffffffff
1002 16 1 0: 1 0 ffffffff
1001 12 1 1: 1 0 ffffffff
1004 12 1 2: 1 0 ffffffff
1007 24 1 3: ffffffff 0 ffffffff
1007 24 1 4: 1 0 ffffffff
1004 12 1 5: 1 0 ffffffff
1005 16 1 6: 1 0 ffffffff
1004 12 1 7: 1 0 ffffffff
1005 16 1 8: 1 0 ffffffff[/COLOR]
loop
loop
[COLOR="#0000FF"]1004 12 1 9: 1 0 ffffffff
1005 16 1 10: 1 0 ffffffff
1008 16 1 11: 1 0 ffffffff
1008 16 1 12: 2 0 ffffffff
1008 16 1 13: 3 0 ffffffff
1008 16 1 14: 4 0 ffffffff
1008 16 1 15: 5 0 ffffffff
1008 16 1 16: 6 0 ffffffff
1008 16 1 17: 7 0 ffffffff[/COLOR]
loop
loop
[COLOR="#008000"]1009 16 1 18: 5 0 ffffffff[/COLOR]
loop

Red is the same as the post above, i.e when mtp-test starts, blue is when I open "Teensy MTP Disk/Serial" in Nautilus and green is when I try to open a file. Do you see anything that might help?

By the way, what do the other numbers mean?
 
By the way, what do the other numbers mean?
There is a printout at the beginning of mtpd.loop that prints out key info of the mtp requests by PC.
heva a look to this.

I let it in code for exacly this reason, to see exactly what PC requests (and where problems occur)
BTW, you cannot open a file, you only can copy file from/ to Teensy/PC
1009 means you copied file from Teensy to PC
BTW, all Op-codes are in the beginning of the MTP.cpp
 
1009 means you copied file from Teensy to PC
BTW, all Op-codes are in the beginning of the MTP.cpp

Thank you. Found them.
So, the 1003 at line 7 in my serial output means "MTP_OPERATION_CLOSE_SESSION" and then 1002 at line 8 is "MTP_OPERATION_OPEN_SESSION", i.e. an attempt to re-open the session? I am beginning to understand.

BTW, you cannot open a file, you only can copy file from/ to Teensy/PC

Yes, I was aware of this. I meant copy and paste onto the PC. :)

By the way, I now have automatic opening of the Teensy folder when I plug the usb into the PC. It needed a different cable and PC port.
 
@xenington,
I see, you have a session close, this seems 'typical' for Linux. I have on Windows never encountered session close. So, there may be some side effects.
 
I tried it on my Windows 7 partition and it worked perfectly - even opening, editing and saving directly to the sd card.

So, having already gone through an epic battle to get the T4.0 MTP to work on Linux, I am reluctantly going to give up on the T4.1. I may revisit this in the future (I really do want it to work on Linux), but for now, I am moving on to do something else.

Thanks for your help.
 
Anyone got this running on a Mac?
I was able to (somehow) get the test sketch to compile after following the guide (was a little confusing TBH) on a T4.1
With no SD card inserted the Serial monitor displays "No Storage". With an SD Card it just prints out "loop" continuously. I don't see any type of storage mounted when I plug it in or open the Finder.

I'm using TD1.53 Beta1 on a MBP late 2016 running the latest OS .
 
after some googling, apparently MTP is only supported on a limited bases on OSX.
It may be that you need to download a specific driver.

Alternatively, this is not in the instructions but needs to be done:


suspecting that USB transfer status is not stable at high CPU speeds
I activated alternative code in
file: usb.c
function: usb_transfer_status
changed #if 0 to #if 1
 
My T3.6 works with MTP on windows, but I have not been able to get it to work on MAC. I’ve tried several different MTP apps and none can see it.
 
Anyone got this running on a Mac?
I was able to (somehow) get the test sketch to compile after following the guide (was a little confusing TBH) on a T4.1
With no SD card inserted the Serial monitor displays "No Storage". With an SD Card it just prints out "loop" continuously. I don't see any type of storage mounted when I plug it in or open the Finder.

I'm using TD1.53 Beta1 on a MBP late 2016 running the latest OS .

Cannot comment on MAC, but MTP is NOT a File system, so it would not show up as storage. It should show up as portable device.
If you search the web for MTP on MAC-OS, you will find that Apple only supports a subset of MTP (maybe because it came original from Microsoft?)
Concerning Readme guide, you are welcome to suggest improvements.
 
if you have a virtual windows machine or a physical one, give it a try there
I have bootcamp with Windows 10 installed - will give that a try later on.

Cannot comment on MAC, but MTP is NOT a File system, so it would not show up as storage. It should show up as portable device.
If you search the web for MTP on MAC-OS, you will find that Apple only supports a subset of MTP (maybe because it came original from Microsoft?)
Concerning Readme guide, you are welcome to suggest improvements.
Thank you for clarifying, I'll investigate further into it.
Regarding the unclarity of the readme, I did copy usb_desc.h to core but got a ton of compile errors, so I reverted back to the original file that comes with TD. Only after looking into the files that need to be copied, I realised that I would have to edit the existing TD files and add the content from the MTP core files to them, and not replace them. And regarding USB2 I think the only part that needs clarification is where the files should be placed. It wasn't clear to me if it was in core or in the MTP src folder (I placed it in the latter).
 
And regarding USB2 I think the only part that needs clarification is where the files should be placed. It wasn't clear to me if it was in core or in the MTP src folder (I placed it in the latter).

USB2 is setup as a library and should go completely into local libraries. Not to be selectively copied. Of course, you are free to to so, but that was not the intended operation.

re usb_desc.h
IMO, the readme says to edit the specific files, but I try to make it clearer.
 
Thank you!

With a few changes I got this working on a T36 with the built-in SD slot.
Replaced
#include "sd.h"
with
#include "SdFat.h"
SdFatSdioEX SD;

Increased the .name field of the Record struct from 14 to 64 bytes, and then replaced
strcpy(r.name, child.name); ~line 203
with
child.getName(r.name, 64);

change the 12 in (~line 336):
if (strlen(filename) > 12) return 0;
to 62

Remove the 10 from: SD.begin(10)


After this it all looks and works faultlessly (apart from volume space reporting). I'm seeing transfer speeds of around 1Megabyte per second, which is inline with the port type. There's no lag or stuttering of any kind when accessing or copying small or large (using Win7).

Nice work.

Very nice work!
I just spent a couple of days trying to figure out why all my files consisted of getname() headers of some sort followed by 32 ( I think) chars of my actual file data.
If you have any hints as to your troubleshooting thought process, or how you arrived at these changes, I would appreciate it. SD access is something I am very glad to have a wrapper around, but I like to have some idea what was happening and why those code changes fixed it.

Again, thanks for posting!

Regards,
Luc
 
MTP_t4 working well on t3.6

I'm using MTP_t4 https://github.com/WMXZ-EU/MTP_t4 installed following the (brief) instructions given in the ReadMe and have encountered no problems in my T3.6 project.

I am using SdFat v2.0 beta8 rather than the older SdFat, because I need the ExFat support and the direct support for large pre-allocated files to prevent blocking writes that sometimes have unacceptably long latency.

Since I'm using two SD cards in my project (the T3.6 built-in SD adaptor and the AudioBoard SD adaptor) and might want to expose either one of them, I've hacked away at the Mtp_t4 storage library to stop it from defining or initializing a drive, forcing it instead to use an already-defined instance of SdFs that I instantiate in a "drives" class that wraps and extends my drives. I modified storage.h to #include my "drives.h", then call chvol() to set the active drive volume before starting the mtp daemon loop.

This works well for connecting to Windows 10 from my teensy with code compiled under Visual Studio/Visual Micro in Serial+MTP mode.

I've encountered only three issues thus far:

1. The reported drive size is not correct. I recall seeing a patch somewhere that may help with this, but haven't been able to track it down.

2. Once the mtp daemon has run, it's not possible to shut down MTP without power-cycling the teensy. If the daemon does not loop, PC programs that enumerate drives on "ThisPC" will hang "forever" until the USB cable is disconnected or the teensy is powered off. There probably is some way to send a disconnect or teardown request to the PC, but I haven't been able to find it as yet.

3. The USB0 port on the t3.6 is limited by hardware to a maximum speed of 12 Mbps. Copying a gigabyte logging data file from the teensy to the PC thus takes about 15 minutes, so for those larger files it's easier to open the case and pull the card in and out. For updating resource files, however, the MTP connection is a game-changer.

It would be even better if I could use the teensy's USB1 port, which can run at 480 Mbps, but the only person I've found who is using it in device mode had to move everything to the uTasker operating system to get that working. I might go there, but not right now. If anybody knows of any work being done towards device mode support for USB1 on the t3.6, I would love to be pointed in the right direction.

In the meantime, I'm thrilled to have high-speed, low-latency logging on the teensy 3.6 working with MTP drive access from the PC!!
 
One of the problems with the MTP protocol is that it teensy is only a responder. So session management is up to the Host.

Now in order to close a session on linux you unmount the mtp (AFAIK) and on PC you can use the device manager to disable (unmount) and enable (mount) the MTP responder
It may be that there are bugs in the code, but that is I'm using it.
 
Back
Top