EEVblog Electronics Community Forum

Products => Computers => Programming => Topic started by: 741 on November 18, 2020, 02:33:29 pm

Title: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: 741 on November 18, 2020, 02:33:29 pm
When a device has multiple descriptors (and code to support those of course), then are the configurations "one at a time" or can 2 or more classes co-exist simultaneusly  on one USB cable? Eg: HID + CDC. Can I (for example) receive HID IN packets on the PC host controller whilst also being able to send OUT packets to the CDC ('serial') device? Is this where multiple 'Interface Descriptors' come in?
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: tszaboo on November 18, 2020, 02:54:33 pm
Yes, it is possible. They are called "endpoints". CDC is a composite class, literally means that it is designed to be used together with other endpoints.
The inner working is typically black magic with callbacks into undocumented ROM space, so it is not easy to give feedback on this, without knowing what architecture/BSP you are using.
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: Nominal Animal on November 18, 2020, 11:14:58 pm
Teensy microcontrollers from 8-bit AVRs (ATmega32u4, AT90USB1286) to 32-bit Cortex (Kinetis MK20DX128, MK20DX256, MK64FX512, MK66FX1M, and i.MX RT1062) all have native USB interfaces (and NOT an USB-serial bridge chip), and the standard Teensyduino add-on to Arduino provides several such configurations out-of-the-box, including Serial + Keyboard + Mouse + Joystick: three HID endpoints and an USB CDC (ACM) endpoint.  The sources for the LGPL-licensed cores are at GitHub (https://github.com/PaulStoffregen/cores).

For 8-bit AVRs like ATmega32u4, LUFA (http://www.fourwalledcubicle.com/LUFA.php) is an open source USB stack, that implements these also.

Typically, the microcontrollers have a limited number of endpoints it can support.  Even ATmega32u4, which has a full speed USB 1.1 interface (12 Mbit/s), can support four. (And an CDC ACM endpoint on it can do about 1 Mbyte/sec, close to theoretical maximum including the USB protocol overhead; this with just the basic Arduino (Leonardo) USB stack on a cheap eBay $4 Pro Micro clone.)

One "packet" will be reserved for each HID endpoint for each millisecond, but the rest is available for the CDC endpoint.  (I haven't used isochronous endpoints, but simply put, they too get reserved a certain bandwidth; these are used for audio and video and similar time-dependent streams.)

Teensy 4 (i.MX RT1062) has a full speed USB 2.0 (480 Mbit/s), and I haven't yet found its theoretical maximum.  When using USB serial (CDC ACM), the Linux tty layer becomes a bottleneck; even a simple MCU-to-host example (https://forum.pjrc.com/threads/60622-Serial-Communication-Problems-Teensy-4-0?p=237636&viewfull=1#post237636) can achieve >200 Mbit/s (25.7 Mbytes/sec).  Ping-ponging (https://forum.pjrc.com/threads/59587-Help-understanding-odd-USB-Serial-test-results-(Teensy-4-0)?p=230013#post230013) 512-byte messages half-duplex yields over 20 Mbits/s (2.5 Mbytes/sec, or about 5000 such message roundtrips per second).  So, the hardware can definitely do this stuff at ease; it's just the vendor libraries on the MCU and the host OS drivers that can throw a spanner in the works.

(I'm actually playing a bit with the Linux kernel, experimenting if a non-TTY raw character device on one hand, and a socket family on the other hand, that both provide a socket-like interface for USB CDC ACM and USB bulk transfers, would make sense.  I really don't like having to rely on something as fragile and ever-changing as libusb.  We should have learned from ALSA and old graphics drivers how crappy that kind of kernel-library dependency really is.)
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: Tagli on December 17, 2020, 03:31:23 pm
Classes can be defined in interface descriptor. Actually, as far as I have read, this is now the common practice and class definitions in the device descriptor is rare.

Each interface is associated with a single class, defined by USBIF or Vendor Specific (like having no class). Each interface claims some endpoints (or no endpoints). Interfaces can also have alternate settings, which may be useful if different endpoint settings are required depending on the bus load.

Recent versions of ST-Link debuggers are good examples. They have 3 interface at the same time:
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: 741 on March 03, 2021, 09:57:21 am
Am finding this hard going. The start point is a working HID keypad, PIC16F1455. Target is Win 7, 8, 10.

When I try to add CDC functionality, the device still enumerates as a simple HID keyboard. Code is based on the Microchip MLA, "cdc_basic" (and also looking at the composite example "composite_hid_msd").

One new worry is INF files. For Win10, no INF is required for CDC, but otherwise it is needed for 64-bit Windows OS - also, I wonder whether a 'composite device' affects the status of the CDC interface in this respect. Along with that is tackling the 'signing' process.

As a test, I compiled the demo CDC ("cdc_basic\firmware\low_pin_count_usb_development_kit_pic16f1459.x"), just changing the chip to 16F1455, and using the same hardware as the keypad. Absolutely nothing happens when the device is attached (Win7 x64), and no 'box' appears requesting an INF file either, even after attempting to 'discover' new hardware.
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: mon2 on March 03, 2021, 09:30:30 pm
Validate your descriptors using this free tool:

https://www.thesycon.de/eng/usb_descriptordumper.shtml (https://www.thesycon.de/eng/usb_descriptordumper.shtml)

Post your output.
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: 741 on March 04, 2021, 10:17:01 am
Thanks for the link.

<UPDFATED/MODIFIED>

The CDC part of the descriptor was absent for some reason, it seems to be present in the source code.

---> This is partially due to the MPLABX syntax highlighting, whicj is often inconsistent, so I ignored it.

My #define to add CDC is shown grey - but when I try adding an experimental #error, this "proves" the #define is true...

So I do not understand!

Anyway, when I comment out the #ifdef, the descriptor looks good - encouraging.

Code: [Select]
Information for device Keypad (VID=0x1C4F PID=0x0026):

------------------------------
Connection Information:
------------------------------
Device current bus speed: FullSpeed
Device address: 0x0002
Current configuration value: 0x00
Number of open pipes: 0


------------------------------
Device Descriptor:
------------------------------
0x12 bLength
0x01 bDescriptorType
0x0200 bcdUSB
0x00 bDeviceClass     
0x00 bDeviceSubClass   
0x00 bDeviceProtocol   
0x08 bMaxPacketSize0   (8 bytes)
0x1C4F idVendor
0x0026 idProduct
0x0001 bcdDevice
0x01 iManufacturer   "SJB Test"
0x02 iProduct        "Keypad"
0x00 iSerialNumber
0x01 bNumConfigurations


-------------------------
Configuration Descriptor:
-------------------------
0x09 bLength
0x02 bDescriptorType
0x0063 wTotalLength   (99 bytes)
0x02 bNumInterfaces
0x01 bConfigurationValue
0x00 iConfiguration
0xC0 bmAttributes   (Self-powered Device)
0x32 bMaxPower      (100 mA)

Interface Descriptor:
------------------------------
0x09 bLength
0x04 bDescriptorType
0x00 bInterfaceNumber
0x00 bAlternateSetting
0x02 bNumEndPoints
0x03 bInterfaceClass      (Human Interface Device Class)
0x01 bInterfaceSubClass   
0x01 bInterfaceProtocol   
0x00 iInterface

HID Descriptor:
------------------------------
0x09 bLength
0x21 bDescriptorType
0x0111 bcdHID
0x00 bCountryCode
0x01 bNumDescriptors
0x22 bDescriptorType   (Report descriptor)
0x003F bDescriptorLength

Endpoint Descriptor:
------------------------------
0x07 bLength
0x05 bDescriptorType
0x81 bEndpointAddress  (IN endpoint 1)
0x03 bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0008 wMaxPacketSize    (1 x 8 bytes)
0x01 bInterval         (1 frames)

Endpoint Descriptor:
------------------------------
0x07 bLength
0x05 bDescriptorType
0x01 bEndpointAddress  (OUT endpoint 1)
0x03 bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0008 wMaxPacketSize    (1 x 8 bytes)
0x01 bInterval         (1 frames)

Interface Descriptor:
------------------------------
0x09 bLength
0x04 bDescriptorType
0x00 bInterfaceNumber
0x00 bAlternateSetting
0x01 bNumEndPoints
0x02 bInterfaceClass      (Communication Device Class)
0x02 bInterfaceSubClass   (Abstract Control Model - ACM)
0x01 bInterfaceProtocol   (ITU-T V.250)
0x00 iInterface

CDC Header Functional Descriptor:
------------------------------
0x05 bFunctionalLength
0x24 bDescriptorType
0x00 bDescriptorSubtype
0x0110 bcdCDC

CDC Abstract Control Management Functional Descriptor:
------------------------------
0x04 bFunctionalLength
0x24 bDescriptorType
0x02 bDescriptorSubtype
0x00 bmCapabilities

CDC Union Functional Descriptor:
------------------------------
0x05 bFunctionalLength
0x24 bDescriptorType
0x06 bDescriptorSubtype
0x00 bControlInterface
0x01 bSubordinateInterface(0)

CDC Call Management Functional Descriptor:
------------------------------
0x05 bFunctionalLength
0x24 bDescriptorType
0x01 bDescriptorSubtype
0x00 bmCapabilities
0x01 bDataInterface

Endpoint Descriptor:
------------------------------
0x07 bLength
0x05 bDescriptorType
0x81 bEndpointAddress  (IN endpoint 1)
0x03 bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x000A wMaxPacketSize    (1 x 10 bytes)
0x02 bInterval         (2 frames)

Interface Descriptor:
------------------------------
0x09 bLength
0x04 bDescriptorType
0x01 bInterfaceNumber
0x00 bAlternateSetting
0x02 bNumEndPoints
0x0A bInterfaceClass      (CDC Data)
0x00 bInterfaceSubClass   
0x00 bInterfaceProtocol   
0x00 iInterface

Endpoint Descriptor:
------------------------------
0x07 bLength
0x05 bDescriptorType
0x02 bEndpointAddress  (OUT endpoint 2)
0x02 bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0040 wMaxPacketSize    (64 bytes)
0x00 bInterval         

Endpoint Descriptor:
------------------------------
0x07 bLength
0x05 bDescriptorType
0x82 bEndpointAddress  (IN endpoint 2)
0x02 bmAttributes      (Transfer: Bulk / Synch: None / Usage: Data)
0x0040 wMaxPacketSize    (64 bytes)
0x00 bInterval         

Microsoft OS Descriptor is not available. Error code: 0x0000001F


--------------------------------
String Descriptor Table
--------------------------------
Index  LANGID  String
0x00   0x0000  0x0409
0x01   0x0409  "SJB Test"
0x02   0x0409  "Keypad"

------------------------------

Connection path for device:
Standard Enhanced PCI to USB Host Controller
Root Hub
Generic USB Hub
Keypad (VID=0x1C4F PID=0x0026) Port: 2

Running on: Windows 7 with Service Pack 1

Brought to you by TDD v2.17.0, Feb 23 2021, 14:04:02



Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: mon2 on March 04, 2021, 07:46:39 pm
Hi. See if the following helps:

https://www.microchip.com/forums/m756944.aspx (https://www.microchip.com/forums/m756944.aspx)

 I recall that there are signed drivers available from Microchip for their IP. That is, as you are a Microchip customer, do not see an issue with you using the same device and product ID so that your widget can map onto the use of the signed drivers.

So in summary:

a) Windows 10 will auto-support the CDC model using the class code link to your device
b) the older Windows OSes will function using the Microsoft signed UART drivers from Microchip

If you do not take this approach, the project can cost an estimated $2k-$10k USD. These are offshore development rates.

Read my post here:

https://www.xcore.com/viewtopic.php?t=3191 (https://www.xcore.com/viewtopic.php?t=3191)

So change your IDs to the ones from this webpage and test it out with your Windows 7, etc. older operating systems.
Title: Re: USB/Multiple configurations (or interfaces?), HID & CDC etc
Post by: 741 on March 05, 2021, 11:55:19 am
The Microchip forum link looks useful, but I cannot see any reference to this Interface Adapter (IAD) in the curent MLA composite (HID+MSD) example, I do not know if I need to add this descriptor. One issue with the thead  is the internal links, eg to GitHub code are sometimes no longer valid.