embassy icon indicating copy to clipboard operation
embassy copied to clipboard

Implement embedded_io::asynch::Read trait for Uart with DMA on STM32

Open guillaume-michel opened this issue 1 year ago • 3 comments

As discussed in chat, there is a need to implement embedded_io traits for UART + DMA on STM32.

  • First we need to be able to take the UART interrupt for Uart constructor and still be able to split into Rx and Tx part. This requires to adopt the same internal structure as BufferedUarte in NRF.
  • We need to break the constructor of Uart with DMA to take the Uart interrupt
  • Implement embedded_io::asynch::Read trait where the read method of the trait will use DMA (not circular) + Idle line detection and the read_exact will forward to the actual read method of Uart

guillaume-michel avatar Sep 23 '22 10:09 guillaume-michel

the read method of the trait will use DMA (not circular) + Idle line detection

This doesn't work in practice. Code using the Read trait usually assumes that the underlying stream actually behaves like a stream, for example bytes that arrive between read calls are not lost. If RX DMA is only on while a read() call is actually executing, bytes arriving in between will get lost very easily (the UART peripheral has a tiny buffer of only 4 bytes).

This is why BufferedUart exists: it's constantly reading into the buffer, and read() only pops bytes out of the buffer. The only way to lose bytes is if the buffer gets full, which can be tuned to be big enough so it doesn't happen.

What you want probably is BufferedUart using DMA, instead of implementing embedded-io for the non-buffered UART.

Dirbaio avatar Sep 23 '22 16:09 Dirbaio

I understand that there are many ways to combine a peripheral like UART and DMA. BufferedUart with DMA would be great to have but what I really need is read_until_idle for UART with DMA on STM32 the same way it exists in embassy-nrf. With this I could handle variable length messages and avoid beeing stuck waiting for bits which will never come when I miss 1 byte.

I am willing to work on read_until_idle implementation for Uart with DMA. I think the buferredUart + DMA is a more complicated topic and I am not sure I have enough experience to tackle this problem right now.

If you agree on adding a read_until_idle method on Uart I can try to push a PR.

guillaume-michel avatar Sep 26 '22 13:09 guillaume-michel

I think an inherent (not trait) read_until_idle impl makes sense, yes! :+1:

Dirbaio avatar Sep 26 '22 13:09 Dirbaio