Skip to main content
Graduate II
June 27, 2024
Solved

Can USB endpoints be shared between Interface descriptors?

  • June 27, 2024
  • 6 replies
  • 3797 views

The STM32G4 I'm using supports up to 8 hardware USB endpoints. I'd like to it to enumerate as a composite device with 3 CDC-ACM channels (doing so would greatly simplify the host software).

 

Since each CDC-ACM class device requires 3 endpoints one each for data in/out, and one interrupt EP for control.,

I'm one endpoint short of success. However, the control endpoint is only used to signal the desired baud-rate to the MCU, which I can either ignore or set for all three channels uniformly. That is, I don't this endpoint for function, but the spec seems to require it.

 

The question is whether the USB spec actively would allow me to "bend the rules" in this way, by specifying a single end as shared by multiple interfaces. I suspect the device will fail to enumerate, since the OS will reject the descriptors as invalid.

 

Would appreciate anyone who has information to offer about this kind of hack.

 

    This topic has been closed for replies.
    Best answer by gbm

    Your MCU supports 8 endpoint PAIRS = 16 endpoints. You may implement 3 CDCs using 3 bulk pairs and 3 int in endpoints (plus control endpoint pair) and you will still have one endpoint pair free.

    Back in old times it was possible to implement multiple VCOMs with single inactive, unused int in endpoint. Based on my experiments, Windows 11 doesn't support this.

    There is a demo for my USB stack implementing 3 VCOMs:

    https://github.com/gbm-ii/gbmUSBdevice

    6 replies

    Technical Moderator
    July 1, 2024

    Hi @BarryWhit 

    According to USB specifications, Endpoint cannot be shared by interfaces of the same configuration. Each interface is supposed to have its own set of endpoints to ensure that data streams do not interfere with each other, and that the USB host can manage each interface and its endpoints independently.

    gbmAnswer
    Graduate
    July 1, 2024

    Your MCU supports 8 endpoint PAIRS = 16 endpoints. You may implement 3 CDCs using 3 bulk pairs and 3 int in endpoints (plus control endpoint pair) and you will still have one endpoint pair free.

    Back in old times it was possible to implement multiple VCOMs with single inactive, unused int in endpoint. Based on my experiments, Windows 11 doesn't support this.

    There is a demo for my USB stack implementing 3 VCOMs:

    https://github.com/gbm-ii/gbmUSBdevice

    BarryWhitAuthor
    Graduate II
    July 1, 2024

    @gbm Thank you. How could I miss that?

    BarryWhitAuthor
    Graduate II
    July 1, 2024

    (this was actually a response to FBL before I saw gdm's answer)

    And do you know if this part of the spec is strictly enforced? for example, have you ever edited the descriptors manually, and made this mistake, and know for a fact that the OS will reject the device during enumeration?

    Graduate
    July 1, 2024

    It wasn't a mistake :). Some time ago I implemented 5 CDCs on STM32F103, sharing a single, unused interrupt in ep. I tried the same trick few months ago and the device with shared int in was not recognized by Windows. After "unsharing" the int ep it works. I didn't investigate further. The interrupt in endpoint does not need to be active - it may not transfer anything, but it must be unique to an instance of a CDC.

    Technical Moderator
    July 1, 2024

    Indeed @gbm Sorry my bad @BarryWhit , 8 bidirectional endpoints.

    FBL_0-1719839489873.png

    Each unidirectional endpoint can be configured as IN or OUT (Means total 16 uni EP = 8 IN +8 OUT, including the control IN/OUT endpoint). Each of the 8 bidirectional endpoints can be configured either as control, interrupt, bulk or isochronous.

    BarryWhitAuthor
    Graduate II
    July 1, 2024

    Very cool! I actually care more about linux. Don't suppose you know about that, but at least by your windows experience it might work. and I could always also hack the kernel code anyway. Many thanks.

    Graduate
    July 1, 2024

    You don't need any tricks to implement up to 3 CDCs. 6 would be possible if the trick worked.

    BarryWhitAuthor
    Graduate II
    July 1, 2024

    Shouldn't that be 4 max without any sharing?

    EP0 (IN+OUT)+3*(Bulk IN+Bulk OUT+Interrupt In)=2+3*(1+1+1)=11 <=16 :thumbs_up:

    EP0 (IN+OUT)+4*(Bulk IN+Bulk OUT+Interrupt In)=2+4*(1+1+1)=14 <=16 :thumbs_up:

    EP0 (IN+OUT)+5*(Bulk IN+Bulk OUT+Interrupt In)=2+5*(1+1+1)=17 > 16 :thumbs_down:

     

    and  with sharing

    EP0 (IN+OUT)+Interrupt_shared+6*(Bulk IN+Bulk OUT)=2+1+6*(1+1)=15 <=16

    as you said.

    Graduate
    July 1, 2024

    In  a single pair, there may be one in and one out endpoint, both of the same type. So three pairs may be used as bulk in+out for data traffic and three pairs  may be used for providing one interrupt in ep each. There will be one pair left but no extra int in will be possible, needed for the fourth CDC VCOM.