From 61df5113a25b7ce5a057eb6fd2e1e940199b07f0 Mon Sep 17 00:00:00 2001 From: morgan Date: Wed, 9 Oct 2024 10:56:24 +0800 Subject: [PATCH] proto fw: add error correction for 4x char --- src/libboard_artiq/src/cxp_proto.rs | 70 +++++++++++++++++------------ 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/src/libboard_artiq/src/cxp_proto.rs b/src/libboard_artiq/src/cxp_proto.rs index 5ac366d..e3d8ae5 100644 --- a/src/libboard_artiq/src/cxp_proto.rs +++ b/src/libboard_artiq/src/cxp_proto.rs @@ -36,6 +36,14 @@ fn get_cxp_crc(bytes: &[u8]) -> u32 { } trait CxpRead { + fn read_u8(&mut self) -> Result; + + fn read_u16(&mut self) -> Result; + + fn read_u32(&mut self) -> Result; + + fn read_u64(&mut self) -> Result; + fn read_exact_4x(&mut self, buf: &mut [u8]) -> Result<(), Error>; fn read_4x_u8(&mut self) -> Result; @@ -45,20 +53,42 @@ trait CxpRead { fn read_4x_u32(&mut self) -> Result; fn read_4x_u64(&mut self) -> Result; - - fn read_u16(&mut self) -> Result; - - fn read_u32(&mut self) -> Result; - - fn read_u64(&mut self) -> Result; } impl CxpRead for Cursor { + fn read_u8(&mut self) -> Result { + let mut bytes = [0; 1]; + self.read_exact(&mut bytes)?; + Ok(bytes[0]) + } + + fn read_u16(&mut self) -> Result { + let mut bytes = [0; 2]; + self.read_exact(&mut bytes)?; + Ok(NetworkEndian::read_u16(&bytes)) + } + + fn read_u32(&mut self) -> Result { + let mut bytes = [0; 4]; + self.read_exact(&mut bytes)?; + Ok(NetworkEndian::read_u32(&bytes)) + } + + fn read_u64(&mut self) -> Result { + let mut bytes = [0; 8]; + self.read_exact(&mut bytes)?; + Ok(NetworkEndian::read_u64(&bytes)) + } + fn read_exact_4x(&mut self, buf: &mut [u8]) -> Result<(), Error> { - for b in buf { - // TODO: add error correction - let mut bytes = [0; 4]; - self.read_exact(&mut bytes)?; - *b = bytes[0]; + for byte in buf { + // Section 9.2.2.1 (CXP-001-2021) + // decoder should immune to single bit errors when handling 4x duplicated characters + let a = self.read_u8()?; + let b = self.read_u8()?; + let c = self.read_u8()?; + let d = self.read_u8()?; + // vote and return majority + *byte = a & b & c | a & b & d | a & c & d | b & c & d; } Ok(()) } @@ -86,24 +116,6 @@ impl CxpRead for Cursor { self.read_exact_4x(&mut bytes)?; Ok(NetworkEndian::read_u64(&bytes)) } - - fn read_u16(&mut self) -> Result { - let mut bytes = [0; 2]; - self.read_exact(&mut bytes)?; - Ok(NetworkEndian::read_u16(&bytes)) - } - - fn read_u32(&mut self) -> Result { - let mut bytes = [0; 4]; - self.read_exact(&mut bytes)?; - Ok(NetworkEndian::read_u32(&bytes)) - } - - fn read_u64(&mut self) -> Result { - let mut bytes = [0; 8]; - self.read_exact(&mut bytes)?; - Ok(NetworkEndian::read_u64(&bytes)) - } } #[derive(Debug)]