Skip to content

Commit

Permalink
Merge pull request #235 from grabpot/fix/splitserial
Browse files Browse the repository at this point in the history
  • Loading branch information
HaoboGu authored Jan 15, 2025
2 parents 05ddfb7 + a3a5489 commit 1718254
Showing 1 changed file with 56 additions and 19 deletions.
75 changes: 56 additions & 19 deletions rmk/src/split/serial/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,44 +42,81 @@ pub(crate) async fn run_serial_peripheral_monitor<
/// Serial driver for BOTH split central and peripheral
pub(crate) struct SerialSplitDriver<S: Read + Write> {
serial: S,
buffer: [u8; SPLIT_MESSAGE_MAX_SIZE],
n_bytes_part: usize,
}

impl<S: Read + Write> SerialSplitDriver<S> {
pub(crate) fn new(serial: S) -> Self {
Self { serial }
Self {
serial,
buffer: [0_u8; SPLIT_MESSAGE_MAX_SIZE],
n_bytes_part: 0,
}
}
}

impl<S: Read + Write> SplitReader for SerialSplitDriver<S> {
async fn read(&mut self) -> Result<SplitMessage, SplitDriverError> {
let mut buf = [0_u8; SPLIT_MESSAGE_MAX_SIZE];
let n_bytes = self
.serial
.read(&mut buf)
.await
.map_err(|_e| SplitDriverError::SerialError)?;
if n_bytes == 0 {
return Err(SplitDriverError::EmptyMessage);
const SENTINEL: u8 = 0x00;
while self.n_bytes_part < self.buffer.len() {
let n_bytes = self
.serial
.read(&mut self.buffer[self.n_bytes_part..])
.await
.map_err(|_e| {
self.n_bytes_part = 0;
SplitDriverError::SerialError
})?;
if n_bytes == 0 {
return Err(SplitDriverError::EmptyMessage);
}

self.n_bytes_part = (self.n_bytes_part + n_bytes).min(self.buffer.len());
if self.buffer[..self.n_bytes_part].contains(&SENTINEL) {
break;
}
}
let message: SplitMessage = postcard::from_bytes(&buf).map_err(|e| {
error!("Postcard deserialize split message error: {}", e);
SplitDriverError::DeserializeError
})?;
Ok(message)

let (result, n_bytes_unused) = match postcard::take_from_bytes_cobs::<SplitMessage>(
&mut self.buffer.clone()[..self.n_bytes_part],
) {
Ok((message, unused_bytes)) => (Ok(message), unused_bytes.len()),
Err(e) => {
error!("Postcard deserialize split message error: {}", e);
let n_bytes_unused = self.buffer[..self.n_bytes_part]
.iter()
.position(|&x| x == SENTINEL)
.map_or(0, |index| self.n_bytes_part - index - 1);
(Err(SplitDriverError::SerializeError), n_bytes_unused)
}
};

self.buffer
.copy_within(self.n_bytes_part - n_bytes_unused..self.n_bytes_part, 0);
self.n_bytes_part = n_bytes_unused;

result
}
}

impl<S: Read + Write> SplitWriter for SerialSplitDriver<S> {
async fn write(&mut self, message: &SplitMessage) -> Result<usize, SplitDriverError> {
let mut buf = [0_u8; SPLIT_MESSAGE_MAX_SIZE];
let bytes = postcard::to_slice(message, &mut buf).map_err(|e| {
let bytes = postcard::to_slice_cobs(message, &mut buf).map_err(|e| {
error!("Postcard serialize split message error: {}", e);
SplitDriverError::SerializeError
})?;
self.serial
.write(bytes)
.await
.map_err(|_e| SplitDriverError::SerialError)
let mut remaining_bytes = bytes.len();
while remaining_bytes > 0 {
let sent_bytes = self
.serial
.write(&bytes[bytes.len() - remaining_bytes..])
.await
.map_err(|_e| SplitDriverError::SerialError)?;
remaining_bytes -= sent_bytes;
}
Ok(bytes.len())
}
}

Expand Down

0 comments on commit 1718254

Please sign in to comment.