MTP Responder Contribution

Trying out MTP Responder. Shows up fine on Windows 10 using a Teensy 3.6 with the built-in SD running MTP Blinky with the patch mentioned in the PR applied. I can create folders, but not rename them (i.e. I can make some "New Folder"). Any clues to fix that so the folders / files can be renamed and manipulated in Windows Explorer? Thanks!
 
Trying out MTP Responder. Shows up fine on Windows 10 using a Teensy 3.6 with the built-in SD running MTP Blinky with the patch mentioned in the PR applied. I can create folders, but not rename them (i.e. I can make some "New Folder"). Any clues to fix that so the folders / files can be renamed and manipulated in Windows Explorer? Thanks!

If you look up the code, you will see that rename (aka move) is not implemented.
 
Hey, this is super cool! It seems to work well for me on my Teensy 3.6. Thanks for making it happen and for "MTP (Experimental)" getting pulled into the mainline Teensyduino that we all download by default.

The downside, of course, is that we lose Serial when we are in MTP mode. And by "lose Serial", I mean that I can't seem to invoke usb_serial_class methods (like dtr()).

I've seen in other threads that altering the USB modes is not that hard (certainly not as hard as getting MTP to work in the first place!). Is there any chance that someone here with some skills could do the edit to the USB modes to add serial to the MTP mode and do the pull request to Paul?

(note: I see no reason to have MTP mode *without* Serial, so I would simply add serial to the existing MTP mode. This means that we wouldn't be adding yet another entry in the USB menu. But, others might have other opinions.)

Thanks for the great work! I'd be happy to help as a tester!

Chip
 
Last edited:
Got MTP Responder working on T4
code may be found on GitHub/WMXZ/MTP_t4

directory "copy-of-core" contains modification of core library
until they are merged and distributed with TD these file need to be copied to cores/teensy4

PR requested to update core
 
WOW !!! Thank you WMXZ !!, now we need Teensyduino 1.50 beta with the "MTP Disk (Experimental)" in the Tools. ;)
 
Many thanks to wolfmanjm for getting this to work on Linux. I had all but given up!

Also, thank you to WMXZ for trying it with Teensy 4. I can't get it to work yet, but hopefully will soon.

Compiling the example mtp-test started with errors in files mtp_storage.cpp (line 35) and mtp_storage.h (line 40) stating "SdFat-Beta.h not found". Needed to edit those lines to "SdFat.h"

Now the errors are:

Code:
In file included from /tmp/arduino_build_954478/sketch/main.cpp:4:0:
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP.h:64:70: warning: 'used' attribute ignored [-Wattributes]
   uint8_t data_buffer[MTP_RX_SIZE] __attribute__ ((used, aligned(32)));
                                                                      ^
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP_Storage.cpp: In member function 'void MTPStorage_SD::ScanDir(uint32_t)':
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP_Storage.cpp:180:37: error: conversion from 'FsFile' to non-scalar type 'File {aka File32}' requested
         File child = f_.openNextFile();
                                     ^
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP_Storage.cpp: In member function 'virtual uint32_t MTPStorage_SD::Create(uint32_t, bool, const char*)':
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP_Storage.cpp:333:38: warning: large integer implicitly truncated to unsigned type [-Woverflow]
       OpenFileByIndex(ret, FILE_WRITE);
                                      ^
In file included from /home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP.cpp:30:0:
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP.h:64:70: warning: 'used' attribute ignored [-Wattributes]
   uint8_t data_buffer[MTP_RX_SIZE] __attribute__ ((used, aligned(32)));
                                                                      ^
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP.cpp: In member function 'void MTPD::read_until_short_packet()':
/home/dean/Desktop/arduino-1.8.9/hardware/teensy/avr/libraries/MTP_t4-master/src/MTP.cpp:431:42: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
         done = *((uint32_t *) data_buffer) < MTP_RX_SIZE;
                                          ^
Error compiling for board Teensy 4.0.

This is beyond my capabilities unfortunately.

The TeensySdioDemo example provided in the beta version of SdFat works fine.
 
"SdFat-Beta.h not found"

This is a consequence of using SdFat-Beta together with SdFat.
Please open SdFat-Beta and rename SdFat.h into SdFat-Beta.h

You can use also SdFat (as you do) but then there is no ExFat support (which my application needs) and the "FsFile" must be converted to "File".

At the moment I still debug some issues with copying files from PC to Teensy and to make sure it still works also on T3.6.
keep an eye on Github updates.
 
Making some progress.

All compilation errors disappear after making the following changes:

MTP_storage.cpp....line137....change "File" to "FsFile"
MTP_storage.cpp....line180....change "uint8_t" to "oflag_t"
MTP_storage.h....line158....change "uint8_t" to "oflag_t"

However, some warnings sometimes appear (not always):

Code:
In file included from /tmp/arduino_build_920329/sketch/main.cpp:4:0:
/home/dean/arduino-1.8.10/hardware/teensy/avr/libraries/MTP_t4/src/MTP.h:64:70: warning: 'used' attribute ignored [-Wattributes]
   uint8_t data_buffer[MTP_RX_SIZE] __attribute__ ((used, aligned(32)));
                                                                      ^
In file included from /home/dean/arduino-1.8.10/hardware/teensy/avr/libraries/MTP_t4/src/MTP.cpp:30:0:
/home/dean/arduino-1.8.10/hardware/teensy/avr/libraries/MTP_t4/src/MTP.h:64:70: warning: 'used' attribute ignored [-Wattributes]
   uint8_t data_buffer[MTP_RX_SIZE] __attribute__ ((used, aligned(32)));
                                                                      ^
/home/dean/arduino-1.8.10/hardware/teensy/avr/libraries/MTP_t4/src/MTP.cpp: In member function 'void MTPD::read_until_short_packet()':
/home/dean/arduino-1.8.10/hardware/teensy/avr/libraries/MTP_t4/src/MTP.cpp:431:42: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
         done = *((uint32_t *) data_buffer) < MTP_RX_SIZE;
                                          ^

IDE fails to upload automatically to the Teensy, but pressing the button seems to work (red LED shows activity). However, the Teensy is not found by Nautilus.

Hope this helps. I will keep watching Github for updates.
 
updated GitHub.
Note: code is only tested with Teensy4.0 and Windows 10.
Code for T3.x is included but not tested (code has worked in the past with Bill Greiman`s SdFs, which he is not supporting anymore. therefor switch to SdFat-beta).
 
Also, for use with Teensy 3.6, I assume that I copy the "copy-of-core" files over to the Teensy3 core?

Assuming that this was the right thing to do (and after making the other changes that you said in your readme), I get the following compilation errors:

Code:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_dev.h:61:40: error: 'NUM_ENDPOINTS' was not declared in this scope

 extern uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS];

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_dev.h: In function 'uint32_t usb_rx_byte_count(uint32_t)':

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_dev.h:66:25: error: 'NUM_ENDPOINTS' was not declared in this scope

         if (endpoint >= NUM_ENDPOINTS) return 0;

                         ^

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_dev.h:67:16: error: 'usb_rx_byte_count_data' was not declared in this scope

         return usb_rx_byte_count_data[endpoint];

                ^

Any suggestions for how I move forward?

Chip
 
Sorry, copy-to-core only for teensy 4.0 (will add that to Instruction) cores/teensy3 remains as is.
 
@ chipaudette
So, if we're not overwriting the Teensy3 usb_desc.h, we're going to get emulated serial, not real serial, right?

Arduino-1.8.10
Teensyduino 1.49
Teensy 3.6 [all Teensy 3.x series]

Unfortunately it doesn't look good, in the boards.txt file [ MS WIN10 C:\--------\arduino-1.8.10\hardware\teensy\avr ] I see this:

teensy36.menu.usb.mtp=MTP Disk (Experimental)
teensy36.menu.usb.mtp.build.usbtype=USB_MTPDISK
teensy36.menu.usb.mtp.fake_serial=teensy_gateway
 
@ WMXZ
Any reasons for this #elif defined(USB_MTPDISK_)<--underscore still in copy-of-core/usb_desc.h

Code:
#elif defined(USB_MTPDISK)
  #define VENDOR_ID             0x16C0
  #define PRODUCT_ID            0x04D1
  #define MANUFACTURER_NAME     {'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN 11
  #define PRODUCT_NAME          {'T','e','e','n','s','y',' ','M','T','P',' ','D','i','s','k'}
  #define PRODUCT_NAME_LEN      15
  #define EP0_SIZE              64


  #define NUM_INTERFACE		      2
  #define NUM_ENDPOINTS         4
  #define SEREMU_INTERFACE      1	// Serial emulation
  #define SEREMU_TX_ENDPOINT    2
  #define SEREMU_RX_ENDPOINT    2
  #define SEREMU_TX_SIZE        64
  #define SEREMU_RX_SIZE        32
  #define SEREMU_TX_INTERVAL    1	 // TODO: is this ok for 480 Mbit speed
  #define SEREMU_RX_INTERVAL    2	 // TODO: is this ok for 480 Mbit speed
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT

  #define MTP_INTERFACE         2 // MTP Disk
  #define MTP_TX_ENDPOINT       3
  #define MTP_RX_ENDPOINT       3
  #define MTP_EVENT_ENDPOINT    4
  #define MTP_TX_SIZE_480       512
  #define MTP_RX_SIZE_480       512
  #define MTP_TX_SIZE_12        64
  #define MTP_RX_SIZE_12        64
  #define MTP_EVENT_SIZE        16
  #define MTP_EVENT_INTERVAL    1

  #define ENDPOINT3_CONFIG	ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT  // ????

[COLOR="#FF0000"]#elif defined(USB_MTPDISK_)
  #define VENDOR_ID		0x16C0
  #define PRODUCT_ID		0x04D1
  #define MANUFACTURER_NAME	{'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN	11
  #define PRODUCT_NAME		{'T','e','e','n','s','y',' ','M','T','P',' ','D','i','s','k'}
  #define PRODUCT_NAME_LEN	15
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         4
  #define NUM_INTERFACE		2
  #define MTP_INTERFACE		1	// MTP Disk
  #define MTP_TX_ENDPOINT	3
  #define MTP_TX_SIZE		64
  #define MTP_RX_ENDPOINT	3
  #define MTP_RX_SIZE		64
  #define MTP_EVENT_ENDPOINT	4
  #define MTP_EVENT_SIZE	16
  #define MTP_EVENT_INTERVAL	10
  #define SEREMU_INTERFACE      2	// Serial emulation
  #define SEREMU_TX_ENDPOINT    1
  #define SEREMU_TX_SIZE        64
  #define SEREMU_TX_INTERVAL    1
  #define SEREMU_RX_ENDPOINT    2
  #define SEREMU_RX_SIZE        32
  #define SEREMU_RX_INTERVAL    2
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
  #define ENDPOINT3_CONFIG	ENDPOINT_TRANSMIT_AND_RECEIVE
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_ONLY[/COLOR]
 
No,
I only kept the original defines and added the underscore so they will never be activated.
 
So, if we're not overwriting the Teensy3 usb_desc.h, we're going to get emulated serial, not real serial, right?

both Teensy3 and Teensy4 use Seremu.
For an USB agnostic, like myself, it was easier to port MTP from Teensy3 to Teensy4 when using Seremu and not true Serial.
After having it working, maybe one could try to replace Seremu with Serial.
Unfortunately, the examples in usb_desc.h are only partially helpful, as Paul uses different complexities in different occasions without explanation and a little bit more reverse engineering is required.
Eg: USB_SERIAL uses
Code:
  #define DEVICE_CLASS		2	// 2 = Communication Class

but USB_SERIAL_HID uses
Code:
#elif defined(USB_SERIAL_HID)
  #define DEVICE_CLASS		0xEF
  #define DEVICE_SUBCLASS	0x02
  #define DEVICE_PROTOCOL	0x01

So Paul uses Misc (0xEF) as device class code and not 0x03. (https://www.usb.org/defined-class-codes)

and USB_MIDI_SERIAL defines NO device class code

there are also inconsistencies with
Code:
  #define CDC_IAD_DESCRIPTOR	1
defined in USB_MIDI_SERIAL and USB_HID_SERIAL but not in USB_SERIAL

A lot of these differences could simply be a left over from Teensy3 and without consequences, but to know requires understanding of all the different USB implementation.
 
After having it working, maybe one could try to replace Seremu with Serial.
Hey I'm working on this right now, not sure if this is all correct yet :eek:

Code:
#elif defined(USB_MTPDISK)
  #define VENDOR_ID	0x16C0
  #define PRODUCT_ID		0x04D1
  #define MANUFACTURER_NAME	{'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN	11
  #define PRODUCT_NAME		{'T','e','e','n','s','y',' ','M','T','P',' ','D','i','s','k'}
  #define PRODUCT_NAME_LEN	15
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         4
  #define NUM_USB_BUFFERS	20
  #define NUM_INTERFACE		2
  #define MTP_INTERFACE		0	// MTP Disk
  #define MTP_TX_ENDPOINT	3
  #define MTP_TX_SIZE		64
  #define MTP_RX_ENDPOINT	3
  #define MTP_RX_SIZE		64
  #define MTP_EVENT_ENDPOINT	4
  #define MTP_EVENT_SIZE	16
  #define MTP_EVENT_INTERVAL	10
  #define SEREMU_INTERFACE      1	// Serial emulation
  #define SEREMU_TX_ENDPOINT    1
  #define SEREMU_TX_SIZE        64
  #define SEREMU_TX_INTERVAL    1
  #define SEREMU_RX_ENDPOINT    2
  #define SEREMU_RX_SIZE        32
  #define SEREMU_RX_INTERVAL    2
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
  #define ENDPOINT3_CONFIG	ENDPOINT_TRANSMIT_AND_RECEIVE
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_ONLY

#elif defined(USB_MTPDISK_SERIAL)
  #define VENDOR_ID		    0x16C0
  #define PRODUCT_ID		0x0489 // NOT SURE ABOUT 0x0489, Perhaps this should be 0x04D1 ??
  #define MANUFACTURER_NAME	{'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN	11
  #define PRODUCT_NAME		{'T','e','e','n','s','y',' ','M','T','P',' ','D','i','s','k','/','S','e','r','i','a','l'}
  #define PRODUCT_NAME_LEN	    22
  #define EP0_SIZE		        64
  #define NUM_ENDPOINTS         7 // TODO
  #define NUM_USB_BUFFERS	    30
  #define NUM_INTERFACE		    3
  #define MTP_INTERFACE		    0	// MTP Disk
  #define MTP_TX_ENDPOINT	    3
  #define MTP_TX_SIZE		    64
  #define MTP_RX_ENDPOINT	    3
  #define MTP_RX_SIZE		    64
  #define MTP_EVENT_ENDPOINT	4
  #define MTP_EVENT_SIZE	    16
  #define MTP_EVENT_INTERVAL	10
  #define CDC_IAD_DESCRIPTOR	1
  #define CDC_STATUS_INTERFACE	1
  #define CDC_DATA_INTERFACE	2	// Serial
  #define CDC_ACM_ENDPOINT	    5
  #define CDC_RX_ENDPOINT       6
  #define CDC_TX_ENDPOINT       7
  #define CDC_ACM_SIZE          16
  #define CDC_RX_SIZE           64
  #define CDC_TX_SIZE           64
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
  #define ENDPOINT3_CONFIG	ENDPOINT_TRANSMIT_AND_RECEIVE
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_ONLY
  #define ENDPOINT5_CONFIG  ENDPOINT_TRANSIMIT_ONLY         // CDC_ACM_ENDPOINT	     5
  #define ENDPOINT6_CONFIG  ENDPOINT_RECEIVE_ONLY           // CDC_RX_ENDPOINT       6
  #define ENDPOINT7_CONFIG  ENDPOINT_TRANSIMIT_ONLY         // CDC_TX_ENDPOINT       7

in boards.txt file, need this edit for teensy 3.6:
Code:
teensy36.menu.usb.mtp=MTP Disk (Experimental)
teensy36.menu.usb.mtp.build.usbtype=USB_MTPDISK
teensy36.menu.usb.mtp.fake_serial=teensy_gateway
[COLOR="#FF0000"]teensy36.menu.usb.mtpserial=MTP Disk (Experimental) + Serial
teensy36.menu.usb.mtpserial.build.usbtype=USB_MTPDISK_SERIAL[/COLOR]

This will need a fix:
Code:
#if !defined(USB_MTPDISK)
  #error "You need to select USB Type: 'MTP Disk (Experimental)'"
#endif
 
For Teensy3 you can use the descriptor file made by yoonghm on his GitHub site.
I´m more interested in Teeny4
 
Oh yes I forgot to mention the above code belongs to ---\hardware\teensy\avr\cores\teensy3 usb_desc.h
and there is a typo ENDPOINT_TRANSIMIT_ONLY replace with ENDPOINT_TRANSMIT_ONLY
NOTE: untested code yet

EDIT:
Fix for MTP_Storage.h and MTP.h
Code:
#if !defined(USB_MTPDISK)
  #error "You need to select USB Type: 'MTP Disk (Experimental)'"
#endif
Code:
#if !defined(USB_MTPDISK) && !defined(USB_MTPDISK_SERIAL)
#error "You need to select USB Type: 'MTP Disk (Experimental)' or 'MTP Disk (Experimental) + Serial'"
#endif
 
Last edited:
Back
Top