-
Notifications
You must be signed in to change notification settings - Fork 909
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
Rp2040 uart flush - resolves #3537 #3538
Conversation
335d6a1
to
75c863c
Compare
@soypat do we need a new method? Would it be better to change WriteByte? nrf looks like this:
stm32 looks like this:
ESP32, though, is more like RP2040:
Before we add a Flush method, it seems like we should clarify the semantics of 'WriteByte' - it seems like there's currently no consistency on whether it blocks (or not). Personally, I think not blocking on WriteByte to complete with an explicit |
So maybe we don't need Flush today. If we standardize WriteByte to be flushing I could get by. At the same time I agree with your point on the performance of this solution. I believe we'd eventually implement Flush given enough time since it's a simple change to get performance. Personal opinion/doubt: whole WriteByte==blocking, Write==non-blocking is weird to me, what problem does each solve? I understand the existence of ReadByte, I've used that one a bunch but not so much for WriteByte. |
I don't think it's as simple as WriteByte==blocking, Write==non-blocking, Write is just defined as:
Write will be just as blocking (or not) as WriteByte... It's just that the implementations of WriteByte have inconsistent behaviour. |
Aha, I understand. So if we do include this change the Flush mechanics would have to be extracted from the implementations of WriteByte which do that underneath? Are we sure the blocking is not needed in some of the implementations to prevent overflowing the transmit buffer? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially approved but I think I take it back a bit -- hardware sucks, and, usually, I like to see a timeout on something like this. I've had systems hang when hardware messed up. Also, at least on some hardware, I've seen cases where banging it this hard will cause the hardware to spend its time telling you it's busy when it's supposed to be moving data. Not joking.
I wonder if some sort of 100 microsecond sleep in the loop, and "give up when it has to have flushed", would make sense?
The pico-sdk has a function for what you say called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @kenbell, we should fix the implementation of WriteByte
to block until the byte is fully written. If Write
blocks until it is done, it would be consistent to also let WriteByte
block until it has fully written the data.
If this becomes a performance problem, I am of the opinion we should instead look into DMA for supported chips, like here: tinygo-org/tinygo-site#342
I initially approved but I think I take it back a bit -- hardware sucks, and, usually, I like to see a timeout on something like this.
Unless the datasheet or errata says there needs to be a timeout, I don't think we should be adding one. If it is needed, it likely indicates a bug somewhere else in the code.
A timeout might make sense when reading a byte because the sender may get stuck for some reason, but I don't see why it would be needed when writing a byte.
So we now have One reservation I have on having WriteByte block is that then you'd never fill up the tx buffer more than a single byte. In this case we should maybe expect an unexported |
Closing since #3832 is merged. |
Resolves #3537
Below are comparisons. First white signal is UART. Notice it shares the SPI busy time. When calling Flush before an SPI transaction it no longer shares busy time.
Before
After