UAC2.0 on STM32

Sounds like a concurrency issue.

I remember tracing thought the call stacks previously and i think the best course of action is to map the protocol state machine and reads. It sounds like the but is being changed at the wrong time (or it needs a lock in place). The odd/even should be bullet proof as part of the state machine with interrupts within the state machine changing the odd/even state or resetting if required.

As that’s really badly documented stm code, i’d be tempted to work from the USB spec state machines and correlate with the code to find what has and has not been put in the code.. then look at where the state switches should go.
 
After some experiments and searching it is found out that source of data loss is odd / even frame bits (USB_OTG_DOEPCTL_SODDFRM / USB_OTG_DOEPCTL_SD0PID_SEVNFRM) in the endpoint DOEPCTL register. By default frame bits were changed in "USB_EPStartXfer(...)" function called through a long chain of other calls. And it seems to be meaningless because by the time bits are changed frame has also already changed. So only part of data is received. I moved odd / even frame bits changing code to USB_ISR (HAL_PCD_IRQHandler) in the place of SOF Interrupt handling. Situation changed. Now "Incomplete isochronous OUT transfer" interrupts rise not as often as before but they do rise. I can hear more, the whole melody but with distortions.
I am sure the reason (may be it's not the only one) of data loss is loss of some odd / even frames, wich in it's turn depends on changing corresponding bits. It's like the bits are changed too late sometimes. Thinking of possible solutions.
Setting of frame parity is essential for SOF feedback and in endpoints as Windows UAC2 does not accept data that has incorrect frame parity. This will result in incomplete isochronous in transfer interrupt. However for out endpoints frame parity should not be an issue. There may be something wrong in how you set up the out endpoint and initialize the transfers. Modifying HAL PCD driver is not how this should be fixed.
 
Situation with "Incomplete isochronous OUT transfer" interrupts is solved. Solution: another ST UAC1 example (which differes from previous one) is taken as a base and rewritten for UAC2 application. I have not tested sound yet, just tried receiving data for some time without further actions with it, which seems to be lossless. I will give feedback.
 
Can't get feedback working. The host machine does not recieve feedback packets reporting error
"buf 0 feedback packet 118 failed, UrbStatus=0xc0000011 (<NULL>), ignoring packet"
Tried different feedback endpoint polling interval value in descriptor, sending feedback packet from SOF interrupt, from Data In complete interrupt, nothing changes. But Incomplete interrupts don't rise. and MCU seems to transmit feedback packets.
Could someone please give an advice what to pay attention to? And when should feedback packets be transmitted exactly: in SOF ISR, when data packets recieved?
 
I noticed you're working on windows. Have you considered using a Linux host? Since it's open source, you'll be able to use it as a reference much more easily. In general, it's also much easier to debug. There has been a lot of paches to UAC 2.0 on linux in the past year, both on the host and device side

https://github.com/torvalds/linux/blob/master/drivers/usb/gadget/function/f_uac2.c

You're not the only one who seems to have problems with the feedback packets https://groups.google.com/g/audio-widget/c/COAfYP2BCzw

The windows driver has been developed by a company called Theyscon. They're the only one to know what's going on there.
I just noticed they've spun-off a competitor device to what you're working on https://usb-hear.com/
You could consider grabbing one, and reverse-engineering the protocol. Since it's made by the same guys, it's the perfect reference.
 
  • Like
Reactions: 1 user
Looking at this USB-HEAR module I was thinking "interesting.. let's try it..".

Then I looked at its price. They must be kidding. "Starting at 169€" ??
And that's for the module. The EVB is 299€.

Regarding this project, it is looking very interesting.

If the aim is to produce an open source USB to I2S interface that supports PCM & DSD, I would be willing to design a high quality prototype PCB to test out how it sounds. And make the pcb design open source of course.
 
  • Like
Reactions: 1 user
Can't get feedback working. The host machine does not recieve feedback packets reporting error
"buf 0 feedback packet 118 failed, UrbStatus=0xc0000011 (<NULL>), ignoring packet"
Tried different feedback endpoint polling interval value in descriptor, sending feedback packet from SOF interrupt, from Data In complete interrupt, nothing changes. But Incomplete interrupts don't rise. and MCU seems to transmit feedback packets.
Could someone please give an advice what to pay attention to? And when should feedback packets be transmitted exactly: in SOF ISR, when data packets recieved?
Here is a simplified scheme of how my FB handling works both with Windows and Linux:
1. Open & flush FB endpoint
2. At SOF interrupt send FB. At first sending store frame number parity.
3. Block sending FB until IN event (i.e. FB accepted) or isochronous incomplete IN event (FB failed, change parity).
Repeat 2 & 3. Send FB only on frame number having same parity.

The parity handling in effect doubles the FB interval but Windows UAC2 driver seems to require that. In Windows UAC2 log the result looks like this:

[0]0000.0000::09/13/2021-12:36:09.394 [USBAudio2](0x01): COMPL OUT buf 0 CurrenLinearPosition=1178880 EVENT
[5]43C0.3954::09/13/2021-12:36:09.394 [USBAudio2](OUT): packetNumber=308 flags=0x00000000 eosPacketLength=15360
[0]0000.0000::09/13/2021-12:36:09.396 [USBAudio2](0x01): buf 2 feedback packet 1 has invalid packet length 0, ignoring packet
[0]0000.0000::09/13/2021-12:36:09.396 [USBAudio2](0x01): buf 2 feedback packet 3 has invalid packet length 0, ignoring packet
[0]0000.0000::09/13/2021-12:36:09.396 [USBAudio2](0x01): buf 2 feedback packet 5 has invalid packet length 0, ignoring packet
[0]0000.0000::09/13/2021-12:36:09.396 [USBAudio2](0x01): buf 2 feedback packet 7 has invalid packet length 0, ignoring packet

So in this case Windows UAC2 driver has accepted FB packets with even numbers. Packets with odd numbers were not sent so they were ignored.
 
  • Like
Reactions: 1 user
If the aim is to produce an open source USB to I2S interface that supports PCM & DSD, I would be willing to design a high quality prototype PCB to test out how it sounds. And make the pcb design open source of course.
The board has existed quite some time already: https://www.diyaudio.com/community/...trumentation-applications.347854/post-6839058

Has both I2S output and input with up to 768k/32 simultaneous play & record.

Here is a picture of a later board revision with MMCX connectors.
 

Attachments

  • usbi2se.jpg
    usbi2se.jpg
    136.8 KB · Views: 152
Last edited:
  • Like
Reactions: 1 user
Windows PC seems to recieve feedback packets. Now UAC2 log looks like this:

[0]0000.0000::12/20/2022-16:06:27.267 [USBAudio2](0x01): COMPL OUT buf 0 CurrenLinearPosition=43680 EVENT
[0]3B34.1AB8::12/20/2022-16:06:27.267 [USBAudio2](OUT): packetNumber=92 flags=0x00000000 eosPacketLength=1920
[0]2734.2B18::12/20/2022-16:06:27.278 [USBAudio2](0x01): COMPL OUT buf 1 CurrenLinearPosition=44160 EVENT
[0]2734.2B18::12/20/2022-16:06:27.278 [USBAudio2]EP 0x01 OUT stream running at PCM ch=2 sz=16/16 sr=48000
[1]3B34.1AB8::12/20/2022-16:06:27.278 [USBAudio2](OUT): pos=43632 smp ts=11842183386138
[1]3B34.1AB8::12/20/2022-16:06:27.278 [USBAudio2](OUT): packetNumber=93 flags=0x00000000 eosPacketLength=1920
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 0 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 2 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 4 has invalid packet length 0, ignoring packet
...............................................
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 124 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 126 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2]EP 0x81 FB stream running
 
Windows PC seems to recieve feedback packets. Now UAC2 log looks like this:

[0]0000.0000::12/20/2022-16:06:27.267 [USBAudio2](0x01): COMPL OUT buf 0 CurrenLinearPosition=43680 EVENT
[0]3B34.1AB8::12/20/2022-16:06:27.267 [USBAudio2](OUT): packetNumber=92 flags=0x00000000 eosPacketLength=1920
[0]2734.2B18::12/20/2022-16:06:27.278 [USBAudio2](0x01): COMPL OUT buf 1 CurrenLinearPosition=44160 EVENT
[0]2734.2B18::12/20/2022-16:06:27.278 [USBAudio2]EP 0x01 OUT stream running at PCM ch=2 sz=16/16 sr=48000
[1]3B34.1AB8::12/20/2022-16:06:27.278 [USBAudio2](OUT): pos=43632 smp ts=11842183386138
[1]3B34.1AB8::12/20/2022-16:06:27.278 [USBAudio2](OUT): packetNumber=93 flags=0x00000000 eosPacketLength=1920
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 0 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 2 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 4 has invalid packet length 0, ignoring packet
...............................................
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 124 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2](0x01): buf 2 feedback packet 126 has invalid packet length 0, ignoring packet
[0]0000.0000::12/20/2022-16:06:27.281 [USBAudio2]EP 0x81 FB stream running
Looks ok to me.
 
Faced to strange situation. On PC side: UAC2 log reports no errors, audio stream running, FB stream running, log looks like above one, On MCU side: no errors detected (Iso IN and OUT InComplete interrupts don't rise), but no audio stream is received, DataOut Events don't rise. It's like PC sends audio data but MCU does not "see" it and does not receive it. But if FB endpoint does not transmit FB data, MCU receives audio stream successully. Tried different FB endpoint numbers without success. By now, don't understand what is happening.
 
Faced to strange situation. On PC side: UAC2 log reports no errors, audio stream running, FB stream running, log looks like above one, On MCU side: no errors detected (Iso IN and OUT InComplete interrupts don't rise), but no audio stream is received, DataOut Events don't rise. It's like PC sends audio data but MCU does not "see" it and does not receive it. But if FB endpoint does not transmit FB data, MCU receives audio stream successully. Tried different FB endpoint numbers without success. By now, don't understand what is happening.
I take it you're not using DMA?
 
On PC side: UAC2 log reports no errors, audio stream running, FB stream running, log looks like above one, On MCU side: no errors detected (Iso IN and OUT InComplete interrupts don't rise), but no audio stream is received, DataOut Events don't rise.
Did host send a "Set Interface" request to select the alternate setting of your output interface? You should then make the first call to USBD_LL_PrepareReceive() for receiving data from host.