UAC2.0 on STM32

Yes, typically 1-3 times when out endpoint is initialized or starts/stops streaming. In the IsoOutIncomplete interrupt handler I do as described in STM32F723 reference manual (Rev3, pages 1341-42).

I just checked that there are no ISO Out interrupts when endpoint is streaming. So only when initialized or start/stop of streaming.
 
Last edited:
If you mean the UAC1 code that Cube generates, it is not a driver but non-working sample code. Nobody has suggested to use that.
And the lack of adequate documentation for the layers underneath... their quirks. As the most of this thread is about.

Anyway, my perspective on that is different. When prototyping when things don't work, you move on and only return if nothing else works better. The HAL libs, if done well would facilitate rapid prototyping aided by CubeMX. They are good for that in many places, but USB is not one of them.

You never know I may encounter issues with the hardware I2S bridges and have to revisit UAC2.0
 
And the lack of adequate documentation for the layers underneath... their quirks. As the most of this thread is about.
STM32 documentation is actually very good. Far above e.g. XMOS. Many of the issues in this thread relate to UAC2 itself, not STM32.
The HAL libs, if done well would facilitate rapid prototyping aided by CubeMX. They are good for that in many places, but USB is not one of them.
USB OTG controller in STM32 (and many other MCUs) is by Synopsys. HAL is just a very thin layer on top of this and works quite well. But the UAC1 example code is unfortunately very crude.
 
In the IsoOutIncomplete interrupt handler I do as described in STM32F723 reference manual (Rev3, pages 1341-42).
The manual has the following points on page 1342
5. For isochronous OUT endpoints with incomplete transfers, the application must discard the data in the memory and disable the endpoint by setting the EPDIS bit in OTG_DOEPCTLx.
6. Wait for the EPDISD interrupt (in OTG_DOEPINTx) and enable the endpoint to receive new data in the next frame.


When I set the EPDIS bit in OTG_DOEPCTL, EPDISD interrupt in OTG_DOEPINT does not occur and both bits EPENA and EPDIS remains setting in OTG_DOEPCTL.
My code always waits for EPDISD interrupt in OTG_DOEPINT which never occurs "while ((epint & USB_OTG_DOEPINT_EPDISD) != USB_OTG_DOEPINT_EPDISD)".
C:
USBD_LL_FlushEP(pdev, AUDIO_OUT_EP);
    
uint32_t USBx_BASE = (uint32_t)USB_OTG_HS;
if ((USBx_OUTEP(AUDIO_OUT_EP)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
{
    USBx_OUTEP(AUDIO_OUT_EP)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;

    uint32_t epint = USB_ReadDevOutEPInterrupt(USB_OTG_HS, AUDIO_OUT_EP);
    while ((epint & USB_OTG_DOEPINT_EPDISD) != USB_OTG_DOEPINT_EPDISD)
        epint = USB_ReadDevOutEPInterrupt(USB_OTG_HS, AUDIO_OUT_EP);

    CLEAR_OUT_EP_INTR(AUDIO_OUT_EP, USB_OTG_DOEPINT_EPDISD);
}

USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, USBPacket, AUDIO_OUT_PACKET_MAX);
Do you follow the points 5 and 6 mentioned above and disable out endpoint?
 
I do not set EPDIS and wait for EPDISD interrupt. I don't think that would help much if ISO Out Incomplete interrupts are frequent which indicates that something more serious is the cause.

I studied this a bit further. There should be no ISO Out Incomplete interrupts during streaming if everything is working normally. When streaming ends (e.g. host stops playing) the latest USBD_LL_PrepareReceive does not get completed so it generates ISO Out Incomplete interrupts until out endpoint is flushed. These interrupts can be discarded as there is no new data to be processed anymore.

As I tested I noticed that ISO Out Incomplete interrupt can easily happen during streaming if application is too slow in reading the data from the FIFO. The single ISO Out interrupt at start of streaming I mentioned earlier was due to me adding a slow debug printf in interrupt routine.

So to sum up: frequent loss of data packets cannot be remedied with ISO Out Incomplete interrupt handler. The root cause is elsewhere.
 
Last edited:
So to sum up: frequent loss of data packets cannot be remedied with ISO Out Incomplete interrupt handler. The root cause is elsewhere.
I see. Just don't know what next step to take with my code, it has UAC2 implementation only. Even tried changing SAI DMA interrupt priority.
@bohrok2610 if I share with you my source code could you please try it with your hardware to be sure that the code doesn't work not my hardware? Or maybe the code works and the hardware is the reason.
 
Have you tried at 48k/16?
Yes I have, the situation is the same: multiple ISO Out Incomplete interrupts occur.

But... it appears, if USB speed is changed from HS to FS the sound is pure and ISO Out Incomplete interrupts don't occur at all, everything works as it should. So the code seems to work properly. The reason is HS mode of USB3300. I'm gonna howl... :headbash:
 
Found NUCLEO-H743ZI2 with STLink based on STM32F723IEK with USB HS port used. Erased STLink firmware and downloaded UAC2 one.
Iso Out Incomplete interrupts do occur if SOF interrupt is enabled. If SOF interrupt is disabled Iso Out Incomplete interrupts do not occur at all during streamig, feedback is sent in DataOut and everything is working fine. Also Iso Out Incomplete interrupts occur when device settings is requested in sound devices list.
@bohrok2610 , do you have SOF interrupt enabled in USBD_LL_Init() (hpcd.Init.Sof_enable value)?
 
@EvSap, one easy optimization would be to increase the SAI DMA buffer size.
Good idea, thank you for advice.
One thing I don't understand is why you check packet parity when sending feedback. As I remember you have bInterval = 1 for feedback endpoint. So feedback is supposed to be sent every frame. But with packet parity checking a half of feedback packets is skipped, so feedback is sent every second frame and is processed like bInterval would be 2, therefore UAC2 log reports errors for every second feedback packet. Could you please explain this?