cancel
Showing results for 
Search instead for 
Did you mean: 

Can USB endpoints be shared between Interface descriptors?

BarryWhit
Senior III

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.

 

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.
1 ACCEPTED SOLUTION

Accepted Solutions
gbm
Lead III

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

View solution in original post

10 REPLIES 10
FBL
ST Employee

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.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

gbm
Lead III

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

BarryWhit
Senior III

(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?

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.
FBL
ST Employee

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.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

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.

@gbm Thank you. How could I miss that?

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.
BarryWhit
Senior III

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.

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.

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

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 

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

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

 

and  with sharing

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

as you said.

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.