<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>How to switch device between MSC and HID?</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/28514/how-to-switch-device-between-msc-and-hid</link><description> 
Hi there! 
I&amp;#39;m working on a device that&amp;#39;s currently setup as a USB mass storage
device. Now I&amp;#39;ve added HID functionality as per the following
descriptor: 

 
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint,</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: How to switch device between MSC and HID?</title><link>https://community.arm.com/thread/127148?ContentTypeID=1</link><pubDate>Fri, 14 Oct 2011 10:14:19 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:d996b891-da9b-4acc-83ed-8bc15b8f0b0f</guid><dc:creator>Chinzei Tsuneo</dc:creator><description>&lt;p&gt;&lt;p&gt;
You don&amp;#39;t like composite device.&lt;br /&gt;
Then, another option is soft-detach / swap descriptors / soft
attach.&lt;br /&gt;
You have to swap all descriptors including the device descriptor, to
assign another VID/PID to the device. If the MSC would have the same
VID/PID as HID, Windows should get confused.&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to switch device between MSC and HID?</title><link>https://community.arm.com/thread/119514?ContentTypeID=1</link><pubDate>Fri, 14 Oct 2011 09:57:17 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3f17eb24-65f3-4e3c-ac79-62cea57fbd70</guid><dc:creator>Chinzei Tsuneo</dc:creator><description>&lt;p&gt;&lt;p&gt;
Ah, you want to switch HID/MSC using alternate interface, but it
can&amp;#39;t.&lt;br /&gt;
Alternate interface(s) should have the same interface class as the
default interface.&lt;br /&gt;
Alternate interface is supposed to change endpoints, not the
interface class.&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;9.6.5 Interface&lt;/b&gt; (usb_20.pdf)&lt;br /&gt;
&lt;i&gt;An interface may include alternate settings that allow the
endpoints and/or their characteristics to be varied after the device
has been configured.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to switch device between MSC and HID?</title><link>https://community.arm.com/thread/105391?ContentTypeID=1</link><pubDate>Fri, 14 Oct 2011 01:23:54 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e498d6d4-823d-4dac-9006-6d621c6f50e0</guid><dc:creator>Peter Parker</dc:creator><description>&lt;p&gt;&lt;p&gt;
Thanks for the advice regarding OSs. So I&amp;#39;m dropping the idea of
using different configurations and focusing on using alternate
settings.&lt;/p&gt;

&lt;p&gt;
&amp;gt; &lt;i&gt;The interface number of the MSC interface should be
1&lt;/i&gt;&lt;br /&gt;
Should it? I thought the whole point of using alternate settings is
to share the interface (Axelson: &amp;quot;When a configuration supports
multiple, mutually exclusive interfaces, each of the interfaces has a
descriptor with the same value in bInterfaceNumber and a unique value
in bAlternateSetting&amp;quot;). That&amp;#39;s also why my usbcfg looks like this,
with USB_HID_IF_NUM==USB_MSC_IF_NUM:&lt;/p&gt;

&lt;pre&gt;
#define USB_POWER           0
#define USB_IF_NUM          1
#define USB_EP_NUM          32
#define USB_MAX_PACKET0     8
#define USB_DMA             0
#define USB_DMA_EP          0x00000000

#define USB_POWER_EVENT     1
#define USB_RESET_EVENT     1
#define USB_SUSPEND_EVENT   0
#define USB_RESUME_EVENT    0
#define USB_WAKEUP_EVENT    0
#define USB_SOF_EVENT       0
#define USB_ERROR_EVENT     0
#define USB_EP_EVENT        0x0007
#define USB_CONFIGURE_EVENT 1
#define USB_INTERFACE_EVENT 1
#define USB_FEATURE_EVENT   0

#define USB_CLASS           1
#define USB_HID             1
#define USB_HID_IF_NUM      0
#define USB_MSC             1
#define USB_MSC_IF_NUM      0
#define USB_AUDIO           0
#define USB_ADC_CIF_NUM     0
#define USB_ADC_SIF1_NUM    1
#define USB_ADC_SIF2_NUM    2
#define USB_CDC             0
#define USB_CDC_CIF_NUM     0
#define USB_CDC_DIF_NUM     1
#define USB_CDC_BUFSIZE     64

#define USB_VENDOR          0
&lt;/pre&gt;

&lt;p&gt;
Besides, if I set USB_MSC_IF_NUM to 1, I&amp;#39;m back to the composite
device which works fine, but doesn&amp;#39;t allow me to turn off the
MSC.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to switch device between MSC and HID?</title><link>https://community.arm.com/thread/91272?ContentTypeID=1</link><pubDate>Fri, 14 Oct 2011 00:51:46 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:59567cc2-a577-4c5d-8e1c-19d80f95a668</guid><dc:creator>Chinzei Tsuneo</dc:creator><description>&lt;p&gt;&lt;p&gt;
The interface number of the MSC interface should be 1&lt;/p&gt;

&lt;pre&gt;
/* Interface 0, Alternate Setting 1, MSC Class */
  ...
  0x00,                              /* bInterfaceNumber */  // &amp;lt;--- 0x01 (or USB_MSC_IF_NUM)
&lt;/pre&gt;

&lt;p&gt;
Did you touch to usbcfg.h, too?&lt;/p&gt;

&lt;pre&gt;
usbcfg.h

#define USB_IF_NUM          1      // &amp;lt;--- 2

#define USB_EP_EVENT        0x0003 // &amp;lt;--- 0x0007

#define USB_CLASS           1
#define USB_HID             1
#define USB_HID_IF_NUM      0
#define USB_MSC             0       // &amp;lt;--- 1
#define USB_MSC_IF_NUM      0       // &amp;lt;--- 1
&lt;/pre&gt;

&lt;p&gt;
&lt;i&gt;&amp;gt; What would be the best way to create a
runtime-configurable USB device? In the best case by switching
between its modes on the device itself (as opposed to sending some
USB command).&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
USB spec allows that a device may have two or more configurations.
However, OS (especially Windows) doesn&amp;#39;t support configurations
switch well. A composite device, as you did, is practical in most
cases.&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to switch device between MSC and HID?</title><link>https://community.arm.com/thread/59947?ContentTypeID=1</link><pubDate>Thu, 13 Oct 2011 08:18:31 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:dc9edcac-5710-4090-adb8-132f8771c7bc</guid><dc:creator>Peter Parker</dc:creator><description>&lt;p&gt;&lt;p&gt;
SORRY, TYPO ABOVE: in reality, the comma after
&amp;quot;USB_CONFIG_BUS_POWERED&amp;quot; is not missing.&lt;/p&gt;

&lt;p&gt;
So for the alternate interfaces I&amp;#39;m using the following
descriptor:&lt;/p&gt;

&lt;pre&gt;
const U8 USB_ConfigDescriptor[] = {
/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
  WBVAL(                             /* wTotalLength */
    1*USB_CONFIGUARTION_DESC_SIZE +
    2*USB_INTERFACE_DESC_SIZE     +
      HID_DESC_SIZE               +
    4*USB_ENDPOINT_DESC_SIZE
  ),
  0x01,                              /* bNumInterfaces */
  0x01,                              /* bConfigurationValue: 0x01 is used to select this configuration */
  0x04,                              /* iConfiguration */
  USB_CONFIG_BUS_POWERED,            /* bmAttributes */
  USB_CONFIG_POWER_MA(100),          /* bMaxPower, device power consumption is 100 mA */

/* Interface 0, Alternate Setting 0, HID Class */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
  0x00,                              /* bInterfaceNumber */
  0x00,                              /* bAlternateSetting */
  0x02,                              /* bNumEndpoints */
  USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
  HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
  HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
  0x05,                              /* iInterface */

/* HID Class Descriptor */
/* HID_DESC_OFFSET = 0x0012 */
  HID_DESC_SIZE,                     /* bLength */
  HID_HID_DESCRIPTOR_TYPE,           /* bDescriptorType */
  WBVAL(0x0100), /* 1.00 */          /* bcdHID */
  0x00,                              /* bCountryCode */
  0x01,                              /* bNumDescriptors */
  HID_REPORT_DESCRIPTOR_TYPE,        /* bDescriptorType */
  WBVAL(HID_REPORT_DESC_SIZE),       /* wDescriptorLength */

/* Endpoint, EP1 Interrupt IN */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(1),                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x20,          /* 32ms */          /* bInterval */

/* Endpoint, EP1 Interrupt OUT */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(1),               /* bEndpointAddress */
  USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x20,          /* 32ms */          /* bInterval */

/* Interface 0, Alternate Setting 1, MSC Class */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
  0x00,                              /* bInterfaceNumber */
  0x01,                              /* bAlternateSetting */
  0x02,                              /* bNumEndpoints */
  USB_DEVICE_CLASS_STORAGE,          /* bInterfaceClass */
  MSC_SUBCLASS_SCSI,                 /* bInterfaceSubClass */
  MSC_PROTOCOL_BULK_ONLY,            /* bInterfaceProtocol */
  0x07,                              /* iInterface */

/* Endpoint, EP2 Bulk IN */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(2),                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,            /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x00,                              /* bInterval: ignore for Bulk transfer */

/* Endpoint, EP2 Bulk OUT */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(2),               /* bEndpointAddress */
  USB_ENDPOINT_TYPE_BULK,            /* bmAttributes */
  WBVAL(0x0040),                     /* wMaxPacketSize */
  0x00,                              /* bInterval: ignore for Bulk transfer */

/* Terminator */
  0                                  /* bLength */
};
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
This doesn&amp;#39;t work as in: my PC host application (the famous
HIDClient.exe) freezes after selecting the HID - enumeration is fine,
though.&lt;/p&gt;

&lt;p&gt;
What would be the best way to create a runtime-configurable USB
device? In the best case by switching between its modes on the device
itself (as opposed to sending some USB command). After all, am I
better off using different configurations?&lt;/p&gt;

&lt;p&gt;
Best wishes,&lt;br /&gt;
Peter&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>