Allow configuring whether to care about the CTS line - #66
Conversation
|
thanks for bringing this up! I just returned from vacation and will take a look into that in the following days (hopefully) |
There was a problem hiding this comment.
Thanks for your contribution:
Please:
- change the commit title to:
config: allow disabling CTS check - Add a why comment to the commit message body: Why is this necessary (Real hardware, which one) and why is this a good default
- add a changelog entry like this
**Breaking:** ready_to_send()` doesn't check `MSR::CTS` anymore by default because <insert concise reason>. For manual checks, users can check `if device.msr().contains(MSR::CTS) {}`. This field is configurable in the `Config`.
| /// Whether parity bits should be used. | ||
| pub parity: Parity, | ||
| /// Whether to wait for CTS before sending. | ||
| pub observe_cts: bool, |
There was a problem hiding this comment.
Please rename to check_cts_before_sending.
And please extend the rustdoc like this:
/// Whether to wait for CTS before sending.
///
/// Only activate this if.. keep it off if ...
pub check_cts_before_sending: bool,something concise yet helpful.
| // Software flow control. TODO, what to do with hardware flow control? | ||
| // Is this something we can and should support? | ||
| if !mcr.contains(MCR::LOOP_BACK) && !msr.contains(MSR::CTS) { | ||
| if self.config.observe_cts && !mcr.contains(MCR::LOOP_BACK) && !msr.contains(MSR::CTS) { |
There was a problem hiding this comment.
I think this is not correct or at least difficult to read. How about we slightly rewrite it to keep it readable:
if mcr.contains(MCR::LOOP_BACK) {
return Ok(());
}
if self.config.check_cts_before_sending {
let mcr = self.mcr();
if !mcr.contains(MCR::LOOP_BACK) {
let msr = self.msr();
if !msr.contains(MSR::CTS) {
return Err(ByteSendError::RemoteNotClearToSend);
}
}
}
Ok(());WDYT? It is a little nested and ugly but I prefer it over smart collapsed statements.
ping @mkroening
Most modern hardware only hooks up the RX and TX lines, and doesn't bother with the flow control pins. This means that, in practice, waiting for CTS before sending data will prevent the UART from working, without a clear indication of what's wrong. This commit introduces an option for configuring whether the CTS line should be checked before sending data. We default to not checking the CTS line, believing that: - it's a more useful default on modern hardware, with receive FIFO overruns being virtually unheard of despite the lack of a CTS pin; - even when the CTS line is usefully exposed, ignoring its state leads to more useful behavior when the UART is not connected, for the usecase of emitting logs – logging into the void is better than hanging the system. - when hardware flow control is necessary, the clear symptom of FIFO overruns should be much easier to track down than a silent hang.
af53d16 to
fe65e0b
Compare
|
I've applied the changes you requested, although I instead renamed the Config field to |
|
Lovely, thanks :) |
| // Software flow control. TODO, what to do with hardware flow control? | ||
| // Is this something we can and should support? |
There was a problem hiding this comment.
Now that you mention it, possibly so? I previously assumed that "software flow control" meant "we're driving the flow control lines manually instead of configuring the UART to do it for us", but now that I've looked it up, it appears that software flow control usually refers to using the ASCII XON/XOFF characters for in-band signaling.
There was a problem hiding this comment.
I'm also not 100 percent sure about software and hardware flow control. I tried my best by reading the spec and experimenting on real hardware. Any improvement to the (likely unnecessary?) comment is highly appreciated
We might also just remove that comment. WDYT @meithecatte?
makubacki
left a comment
There was a problem hiding this comment.
Thanks! This resolved the issue I was having with v0.6.0.
Resolves #65.
I have chosen to make "ignore CTS" the default, as that is the choice that is more likely to simply work for the user, as the aforementioned issue demonstrates.
Since the PR adds a new field to the
Configstruct, it would probably need to be a semver bump. Perhaps that's a good opportunity to mark theConfigstruct as#[non_exhaustive], but I'll leave that call up to you.