2024-06-27 12:30 PM - edited 2024-06-28 02:20 PM
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.
Solved! Go to Solution.
2024-07-01 04:42 AM - edited 2024-07-01 04:44 AM
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
2024-07-01 02:43 AM
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.
2024-07-01 04:42 AM - edited 2024-07-01 04:44 AM
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
2024-07-01 06:05 AM - edited 2024-07-01 07:00 AM
(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?
2024-07-01 06:10 AM - edited 2024-07-01 06:11 AM
Indeed @gbm Sorry my bad @BarryWhit , 8 bidirectional endpoints.
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.
2024-07-01 06:15 AM
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.
2024-07-01 06:55 AM
@gbm Thank you. How could I miss that?
2024-07-01 06:58 AM - edited 2024-07-01 07:01 AM
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.
2024-07-01 12:44 PM
You don't need any tricks to implement up to 3 CDCs. 6 would be possible if the trick worked.
2024-07-01 01:06 PM - edited 2024-07-01 01:07 PM
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.