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 a post has answered your question, please acknowledge the help you received by clicking "Accept as Solution".
- Once you've solved your issue, please consider posting a summary of any additional details you've learned. Your new knowledge may help others in the future.
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 a post has answered your question, please acknowledge the help you received by clicking "Accept as Solution".
- Once you've solved your issue, please consider posting a summary of any additional details you've learned. Your new knowledge may help others in the future.
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 a post has answered your question, please acknowledge the help you received by clicking "Accept as Solution".
- Once you've solved your issue, please consider posting a summary of any additional details you've learned. Your new knowledge may help others in the future.
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 a post has answered your question, please acknowledge the help you received by clicking "Accept as Solution".
- Once you've solved your issue, please consider posting a summary of any additional details you've learned. Your new knowledge may help others in the future.

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 a post has answered your question, please acknowledge the help you received by clicking "Accept as Solution".
- Once you've solved your issue, please consider posting a summary of any additional details you've learned. Your new knowledge may help others in the future.