-
Notifications
You must be signed in to change notification settings - Fork 935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stm32: fix buffered uart flush #2416
stm32: fix buffered uart flush #2416
Conversation
@Dirbaio test fails and by clicking I got:
|
bender run |
2d7ac24
to
ded2bc0
Compare
ded2bc0
to
61439a8
Compare
This is off topic, but just noting There's no interrupt based way to tell when the sending is done, you have to busy poll the "tx idle" flag to determine when the FIFO is really empty. |
I started to test my fix on STM32F411 and it does not work in there. It seems RM says this about
I am currently figuring out how to do it properly. |
usart_v4 uses internal FIFO and therefore actually all bytes are not yet sent out although state.tx_buf.is_empty()
usart_v4 uses TC interrupt to see if all bytes are sent out from the FIFO and waker is called from this interrupt. This minimises unnecessary wakeups during sending.
Byte was written to TDR and right after that waker was called. This means `flush` would see that `tx_buf` is empty and can return Ready although actually hardware was still writing this last byte to the wire. With this change non `usart_v4 ` variants would also use TC interrupt to check when last byte was sent out.
unwraps take more space because of panics
There is one caveat. For some reason with first send using usart_v1/usart_v2 TC flag appears right after first byte from buffer is written to DR. Consecutive transfers work as expected - TC flag appears when last byte is fully transferred to wire.
0a6f4c9
to
ec2e3de
Compare
usart_v4
uses internal FIFO and therefore actually all bytes are not yet sent out althoughstate.tx_buf.is_empty()
.Code to demonstrate the problem:
Here red line shows

pin
. Soflush
finishes although in reality 9 bytes were not yet sent out from the FIFO.With this patch

flush
finishes right after TX is done.STM32G0 reference manual
Page 1008:
USART_TDR
register. Repeat this for each data to be transmitted in case of single buffer.USART_TDR
clears theTXE
flag.USART_TDR
adds one data to the TXFIFO. Write operations to theUSART_TDR
are performed whenTXFNF
flag is set. This flag remains set until the TXFIFO is full.USART_TDR
register, wait untilTC = 1
.TODO
flush
would return 1 byte time too early for nonusart_v4
implementation. Final byte is written to register and after thatflush
can see thattx_buf
is empty and it returnsReady
although actually final bytes is still being written to the wire.usart_v4
(STM32G081).usart_v2
(STM32F411).DR
. Consecutive transfers works as expected. 0a6f4c9