forked from M-Labs/artiq-zynq
proto fw: add error correction for 4x char
This commit is contained in:
parent
cbbf6f72f9
commit
61df5113a2
|
@ -36,6 +36,14 @@ fn get_cxp_crc(bytes: &[u8]) -> u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CxpRead {
|
trait CxpRead {
|
||||||
|
fn read_u8(&mut self) -> Result<u8, Error>;
|
||||||
|
|
||||||
|
fn read_u16(&mut self) -> Result<u16, Error>;
|
||||||
|
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Error>;
|
||||||
|
|
||||||
|
fn read_u64(&mut self) -> Result<u64, Error>;
|
||||||
|
|
||||||
fn read_exact_4x(&mut self, buf: &mut [u8]) -> Result<(), Error>;
|
fn read_exact_4x(&mut self, buf: &mut [u8]) -> Result<(), Error>;
|
||||||
|
|
||||||
fn read_4x_u8(&mut self) -> Result<u8, Error>;
|
fn read_4x_u8(&mut self) -> Result<u8, Error>;
|
||||||
|
@ -45,20 +53,42 @@ trait CxpRead {
|
||||||
fn read_4x_u32(&mut self) -> Result<u32, Error>;
|
fn read_4x_u32(&mut self) -> Result<u32, Error>;
|
||||||
|
|
||||||
fn read_4x_u64(&mut self) -> Result<u64, Error>;
|
fn read_4x_u64(&mut self) -> Result<u64, Error>;
|
||||||
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error>;
|
|
||||||
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error>;
|
|
||||||
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error>;
|
|
||||||
}
|
}
|
||||||
impl<Cursor: Read> CxpRead for Cursor {
|
impl<Cursor: Read> CxpRead for Cursor {
|
||||||
fn read_exact_4x(&mut self, buf: &mut [u8]) -> Result<(), Error> {
|
fn read_u8(&mut self) -> Result<u8, Error> {
|
||||||
for b in buf {
|
let mut bytes = [0; 1];
|
||||||
// TODO: add error correction
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(bytes[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u16(&mut self) -> Result<u16, Error> {
|
||||||
|
let mut bytes = [0; 2];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(NetworkEndian::read_u16(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Error> {
|
||||||
let mut bytes = [0; 4];
|
let mut bytes = [0; 4];
|
||||||
self.read_exact(&mut bytes)?;
|
self.read_exact(&mut bytes)?;
|
||||||
*b = bytes[0];
|
Ok(NetworkEndian::read_u32(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u64(&mut self) -> Result<u64, Error> {
|
||||||
|
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 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -86,24 +116,6 @@ impl<Cursor: Read> CxpRead for Cursor {
|
||||||
self.read_exact_4x(&mut bytes)?;
|
self.read_exact_4x(&mut bytes)?;
|
||||||
Ok(NetworkEndian::read_u64(&bytes))
|
Ok(NetworkEndian::read_u64(&bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> {
|
|
||||||
let mut bytes = [0; 2];
|
|
||||||
self.read_exact(&mut bytes)?;
|
|
||||||
Ok(NetworkEndian::read_u16(&bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> {
|
|
||||||
let mut bytes = [0; 4];
|
|
||||||
self.read_exact(&mut bytes)?;
|
|
||||||
Ok(NetworkEndian::read_u32(&bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> {
|
|
||||||
let mut bytes = [0; 8];
|
|
||||||
self.read_exact(&mut bytes)?;
|
|
||||||
Ok(NetworkEndian::read_u64(&bytes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
Loading…
Reference in New Issue