Switching USB device type in software

Status
Not open for further replies.

murpia

Member
Hi,

I'd like to switch USB device types using software, initially just using a push button to detect user input.

Specifically I would like to swap between Serial and MTP but I'm sure the method will be more general. I'm using a Teensy 3.6.

At the moment this seems to be done in the Arduino IDE using the Tools menu, how can it be accomplished in software?

I'm OK if the Teensy needs to reset itself during the process.

Thanks, Ian
 
how can it be accomplished in software?

You need to do pretty much 2 things.

First, a lot of work would be needed to restructure the USB code, so 2 of the descriptor sets and related code are compiled into your program. Of course you'll also need to add some code to select which one to use.

Second, you'll need to add code to shut the USB port off and turn off the internal 1.5K pull up resistor which signals to your PC that a device is connected. To your PC, this will appear as if the cable was physically unplugged. Then when you turn it back on, your PC will believe the cable has been plugged back in. That's your opportunity to have it read the other descriptor set and believe you've plugged in a different device.

If you just want both of these to work, the much simpler approach is to craft a composite descriptor with both interfaces. Then your PC will be able to use both at the same time.
 
If you just want both of these to work, the much simpler approach is to craft a composite descriptor with both interfaces. Then your PC will be able to use both at the same time.
Yes that would be a better approach, if it's indeed feasible. Can you provide any guidance on how to achieve this?

Thanks, Ian
 
Thanks Paul,

All working, my only point of confusion was the difference between SEREMU and CDC when it comes to adding the device...

For anyone who wants to do the same, here's the changes I made.

In 'usb_desc.h' I added the following at line 527:

Code:
#elif defined(USB_MTPDISK_SERIAL)
  #define VENDOR_ID		0x16C0
  #define PRODUCT_ID		0x0489
  #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         5
  #define NUM_USB_BUFFERS	30
  #define NUM_INTERFACE		3
  #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 MTP_INTERFACE		2	// MTP Disk
  #define MTP_TX_ENDPOINT	4
  #define MTP_TX_SIZE		64
  #define MTP_RX_ENDPOINT	4
  #define MTP_RX_SIZE		64
  #define MTP_EVENT_ENDPOINT	5
  #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_TRANSMIT_AND_RECEIVE
  #define ENDPOINT5_CONFIG	ENDPOINT_RECEIVE_ONLY

In 'boards.txt' I added the following at line 63:

Code:
teensy36.menu.usb.mtpserial=MTP Disk (Experimental) + Serial
teensy36.menu.usb.mtpserial.build.usbtype=USB_MTPDISK_SERIAL

Files attached if anyone needs them:

View attachment boards.txt
View attachment usb_desc.h

Regards, Ian
 
@murpia. I am assuming this also would work for the Teensy 3.5 by just adding the same two lines with teensy36 changed to teensy35. Maybe Paul could make this change permanent at some point.
 
Status
Not open for further replies.
Back
Top