FocusSerial: Use `.readBytes()` rather than `.read()` for reading a `char`

`Serial.read()` is unbuffered, and will return `-1` (which we cast to an
unsigned char, so 255) immediately if there is no data in the incoming buffer.
This is unlike every other kind of read we do, which use `parseInt()`, and are
thus buffered reads with a timeout.

The problem with returning `-1` immediately is that Chrysalis sends data in
chunks, so if we end up trying to read a char at a chunk boundary, we'll end up
reading -1s, which we treat as valid data, and cast it to an unsigned char,
completely throwing off the protocol in the process.

By using `readBytes()`, we have a one second window during which more data can
arrive, and as such, is consistent with the rest of our reads.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
pull/1236/head
Gergely Nagy 2 years ago
parent 62a0fae04d
commit a4b84057b0
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -95,7 +95,7 @@ class FocusSerial : public kaleidoscope::Plugin {
color.b = Runtime.serialPort().parseInt(); color.b = Runtime.serialPort().parseInt();
} }
void read(char &c) { void read(char &c) {
c = static_cast<char>(Runtime.serialPort().read()); Runtime.serialPort().readBytes(&c, 1);
} }
void read(uint8_t &u8) { void read(uint8_t &u8) {
u8 = Runtime.serialPort().parseInt(); u8 = Runtime.serialPort().parseInt();

Loading…
Cancel
Save