Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Switching USB device type in software

  1. #1
    Junior Member
    Join Date
    Jun 2017
    Posts
    8

    Switching USB device type in software

    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

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,824
    Quote Originally Posted by murpia View Post
    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.

  3. #3
    Junior Member
    Join Date
    Jun 2017
    Posts
    8
    Quote Originally Posted by PaulStoffregen View Post
    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

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,824
    Quote Originally Posted by murpia View Post
    Can you provide any guidance on how to achieve this?
    Start by reading usb_desc.h, which has extensive comments explaining how to do this.

  5. #5
    Junior Member
    Join Date
    Jun 2017
    Posts
    8
    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:

    boards.txt
    usb_desc.h

    Regards, Ian

  6. #6
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,103
    @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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •