embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.54k stars 768 forks source link

STM32H7 recover from SAI `OverrunError` #3205

Closed elagil closed 3 months ago

elagil commented 3 months ago

Hello!

I use the embassy_stm32::sai::SAI4 peripheral driver on the STM32H723 for writing audio data to a TDM output.

I have to start writing data immediately after calling start() on the driver instance - then it works fine. Otherwise, the writable ring buffer gives an OverrunError, which I cannot recover from, because subsequent calls to write() also give that error immediately. The same happens when there is a pause in writing, and (I guess) that the DMA consumes all of the data in the ring buffer.

I did not find a way to reset the ring buffer (and probably the driver itself). Do I have to make a new driver instance each time? Otherwise, I can also send zeros to the instance, to keep the buffer entertained, but I would rather be able to switch the peripheral off sometimes.

Thanks!

lulf commented 3 months ago

I'm not familiar with SAI, but generally all drivers can be passed a &mut instance upon creation, and when the driver goes out of scope, it switches off the peripheral. Then you can reuse the peripheral with the driver next time you want to use it.

elagil commented 3 months ago

Thanks, I tried that and it works fine. I think I will stick with it.

I--P commented 2 weeks ago

Could you please elaborate on how you fixed that ? I'm running into the same issue with read() and I don't understand how to get rid of the overrun error

elagil commented 2 weeks ago

@I--P You can have a look at this implementation that I ended up with: https://github.com/blus-audio/firmware-rs/blob/main/blus_mini_mk2/src/audio_routing.rs#L325

When there is an error, a fresh SAI instance is created with new_sai4().

I--P commented 2 weeks ago

@elagil thanks a lot, that's what I ended up with too. It will be very helpful for many people to have a direct link to your code here.