MTP Responder Contribution

No, emulated serial is for program downloads only. If you look at all the other 'Serial + ...' options in usb_desc.h you'll see they implement CDC in place of SEREMU.

Compare 'MIDI' to 'Serial + MIDI' as an example. Open the basic Arduino example sketch 'AnalogReadSerial'. The serial monitor only works if you select 'Serial + MIDI'. It doesn't for 'MIDI'. At least not on my PC with a Teensy 3.6. You can see in Windows device monitor that the com port is only there for 'Serial + MIDI'.

Then look into 'usb_desc.h' and you'll see that 'MIDI' implements emulated serial while 'Serial + MIDI' implements CDC. More details in my other post.

Hopefully Paul can correct any errors in my explanation...

Regards, Ian
 
No need to bother Paul.
The "emulated serial" is a simpler and non-standard (I think) usb serial port implementation. It still works with the serial monitor, but will not show up as a CDC device. (Because it's not.)
If it doesn't work on your machine, that's a bug.
 
Possibly 'emulated' just works in the Arduino IDE serial monitor, then?

I needed a real COM port to communicate with a Windows program, hence adding CDC to the MTP example.

Regards, Ian
 
I have converted the file into library. The library could be downloaded from

https://github.com/yoonghm/Teensy_3.x/tree/master/Libraries/MTP

This library requires the following changes
* SdFat libraries - https://github.com/greiman/SdFat-beta/tree/master/SdFat
* <Arduino_path>/hardware/teensy/avr/cores/teensy3/usb_desc.c
* <Arduino_path>/hardware/teensy/avr/cores/teensy3/usb_dev.c
* <Arduino_path>/hardware/boards.txt

I apologize if I missed something, but what changes exactly are required to the above files?

I see that maybe the changes to boards.txt was made for teensy35 & 36 through the pull request mentioned, but how about usb_desc.c and usb_dev.c?

Thanks for the help!
 
Great work!
Is there a way to signal the usb host that an object on the sd card was added, deleted or renamed? I know the mtp specification mentions events to do this, but i have no idea how to implement this.

best regards, Thorvard
 
After some reading and fiddling i found this solution:

I changed in usb_desc.h following line when "MTP_EVENT_ENDPOINT" is defined as 4:

Code:
//  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_ONLY
#define ENDPOINT4_CONFIG	ENDPOINT_TRANSMIT_AND_RECEIVE

Code:
    uint32_t eventID = 1;
 
    void sendEvent(int event, uint32_t param)
    {
      usb_packet_t *eventBuffer;
      eventBuffer = usb_malloc();
      eventBuffer->len = 16;
      eventBuffer->index = 0;
      eventBuffer->next = NULL;
      MTPContainer eventContainer;
      eventContainer.len = 16; // maximum length for an event container
      eventContainer.type = 4; // Type: Event
      eventContainer.op = event; // event code
      /*  the event codes must be included in WriteDescriptor() 
       *  otherwise the responder just ignores the event code
       */
      eventContainer.transaction_id = eventID++;
      eventContainer.params[0] = param;
      memcpy(eventBuffer->buf, (char*)&eventContainer, 16);
      usb_tx(MTP_EVENT_ENDPOINT, eventBuffer);
      /*  the MTP_EVENT_ENDPOINT must be defined as
       *  "ENDPOINT_TRANSMIT_AND_RECEIVE" in 
       *  ...\hardware\teensy\avr\cores\teensy3\usb_desc.h
       */
      get_buffer();
      usb_tx(MTP_EVENT_ENDPOINT, data_buffer_); // send empty packet to finish transaction
      data_buffer_ = NULL;
    }

I hope this helps others using this great library with mtp events.

best regards, Thorvard
 
Sorry for delay, it took time to reinstall, read the forum, update and test again.

I have updated the MTP into https://github.com/yoonghm/MTP, with comments for Teensyduino 1.39.
I have also created an example that call mtpd.loop() only when SD card is present. The example also demonstrate to use Serial port.
The original systick_isr() is removed from the example as it conflicts with the non-weak systick_isr() used by thread library. I did not want to use delay(), so I made use of RTC second timer interrupt, i.e., rtc_seconds_isr().
 
Sorry for delay, it took time to reinstall, read the forum, update and test again.

I have updated the MTP into https://github.com/yoonghm/MTP, with comments for Teensyduino 1.39.
I have also created an example that call mtpd.loop() only when SD card is present. The example also demonstrate to use Serial port.
The original systick_isr() is removed from the example as it conflicts with the non-weak systick_isr() used by thread library. I did not want to use delay(), so I made use of RTC second timer interrupt, i.e., rtc_seconds_isr().

I also came up with the same technique, but with another idea
repeating mtp.loop() while millis()<2000 , e.t.c.
and if USB established, continue loop:D:D

and I found that MTP+Serial doesn't compile with snooze library, though deep sleep and MTP is not commonly used together, and easily overcome
with commenting out the error part in snooze library :eek::eek::eek:
 
You have to check if inserting SD card would cause the K64 to wake up.

There is a thread library, perhaps can try to run two threads, one is to serve MTG, another is to run other tasks.

I think I will add another examples, to write data to the SD periodically. If a file is opened, the on-board LED is turned on, indicating to user not to remove the card.
 
Thank you,
My SD is planned to place constantly.
And MTP is the main access port

And now I plan to use the second USB port on T3.6, So the USB plug can be place at preferred location
Anyone know if the MTP library suits the
Other port? Thanks.
 
There is a severe bug somewhere in the code.
When copying a file with a filename of 24 characters length the teensy hangs. This happens with the blinky example on github, i reported this issue on github.
 
This seems to work very well for my purpose, so thanks for the contribution.

Is there any way to make the device be MTP + Midi? Thanks.
 
I tried messing around with the usb desc in a way that seemed like it should be working (by copying the MTP description into a new board type and adding it to boards.txt) but no joy. Probably missing something. If anyone has it working, I'd love to see their desc. Thanks!
 
And... sorry for the multiple posts. I did get it working as a separate device using the basic MTP example sketch, but since I am also using the SD library there were some conflicts with MTP's use of SDFat which I may try to debug later.
 
If anyone else arrives here and is struggling:

boards.txt added:

teensy36.menu.usb.serialmidimtp=Serial + MIDI + MTP Disk (experimental)
teensy36.menu.usb.serialmidimtp.build.usbtype=USB_MIDI_MTPDISK_SERIAL


usb_desc.h added:

#elif defined(USB_MIDI_MTPDISK_SERIAL)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x04E0
#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','I','D','I'}
#define PRODUCT_NAME_LEN 11
#define EP0_SIZE 64
#define NUM_ENDPOINTS 7
#define NUM_USB_BUFFERS 40
#define NUM_INTERFACE 4
#define CDC_IAD_DESCRIPTOR 1
#define CDC_STATUS_INTERFACE 0
#define CDC_DATA_INTERFACE 1 // Serial
#define CDC_ACM_ENDPOINT 1
#define CDC_RX_ENDPOINT 2
#define CDC_TX_ENDPOINT 3
#define CDC_ACM_SIZE 16
#define CDC_RX_SIZE 64
#define CDC_TX_SIZE 64
#define MIDI_INTERFACE 2 // MIDI
#define MIDI_TX_ENDPOINT 4
#define MIDI_TX_SIZE 64
#define MIDI_RX_ENDPOINT 5
#define MIDI_RX_SIZE 64
#define MTP_INTERFACE 3 // MTP Disk
#define MTP_TX_ENDPOINT 6
#define MTP_TX_SIZE 64
#define MTP_RX_ENDPOINT 6
#define MTP_RX_SIZE 64
#define MTP_EVENT_ENDPOINT 7
#define MTP_EVENT_SIZE 16
#define MTP_EVENT_INTERVAL 10
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT6_CONFIG ENDPOINT_TRANSMIT_AND_RECEIVE
#define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_ONLY
 
@alialiali

I tried to compile MTP_Blinky.ino with no errors but when i load it on teensy 3.5 it blinks but no MTP Drive visible it only shows yellow usb composite drive on Device Manager.. but when i try the original MTP.ino from hubbe it works and it shows the MTP Drive.

What am I missing?? Please Help :(
 
@alialiali

I tried to compile MTP_Blinky.ino with no errors but when i load it on teensy 3.5 it blinks but no MTP Drive visible it only shows yellow usb composite drive on Device Manager.. but when i try the original MTP.ino from hubbe it works and it shows the MTP Drive.

What am I missing?? Please Help :(

Blinky from the library works for me (sorry).
 
@alialiali

Wow..Then Does it Actually shows MTP Drive on ur PC using MTP_Blinky.ino?

Can you teach me how you make it work ?? Please :(
 
Last edited:
@alialiali

Wow..Then Does it Actually shows MTP Drive on ur PC using MTP_Blinky.ino?

Can you teach me how you make it work ?? Please :(

Sorry I can't be more help, but I just compile and upload exactly like the library. Maybe I changed something small, but here is the file just in case:


/*
This example demonstrates MTP with blinky using systick interrupt.
This example tests MTP and SdFat
*/

#include <MTP.h>

MTPStorage_SD storage;
MTPD mtpd(&storage);


volatile int status = 0;
volatile bool sdfound = 0;
volatile int count = 1;

void rtc_seconds_isr() {
if (count-- == 0) {
digitalWrite(LED_BUILTIN, status);
Serial.println("I should be commented out");
status = !status;
if (sdfound)
count = 2;
else
count = 1;
}
}

void setup() {
Serial.begin(19200);
pinMode(LED_BUILTIN, OUTPUT);

RTC_IER |= 0x10; // Enable seconds IRQ from RTC peripheral
NVIC_ENABLE_IRQ(IRQ_RTC_SECOND); // Enable seconds IRS function in NVIC
}

void loop() {
if (SD.begin()) {
sdfound = true;
mtpd.loop();
}
else {
sdfound = false;
}
}


I'm not really sure exactly how it works, and actually I stopped using it myself. I am using 3.6. Sorry again I can't be more helpful.
 
Back
Top