From 3bf10109693024d99ad5961389052d784da857fb Mon Sep 17 00:00:00 2001 From: Astro Date: Sun, 8 Sep 2019 00:47:14 +0200 Subject: [PATCH] ad7172: implement crc checksumming --- firmware/src/ad7172.rs | 35 +++++++++++++++++++++-------------- firmware/src/main.rs | 4 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/firmware/src/ad7172.rs b/firmware/src/ad7172.rs index f9f7d8d..b3e9322 100644 --- a/firmware/src/ad7172.rs +++ b/firmware/src/ad7172.rs @@ -132,9 +132,8 @@ impl From for AdcError { #[repr(u8)] pub enum ChecksumMode { Off = 0b00, + /// Seems much less reliable than `Crc` Xor = 0b01, - /// Not implemented - #[allow(unused)] Crc = 0b10, } @@ -152,7 +151,15 @@ impl Checksum { ChecksumMode::Off => {}, ChecksumMode::Xor => self.state ^= input, ChecksumMode::Crc => { - // TODO + for i in 0..8 { + let input_mask = 0x80 >> i; + self.state = (self.state << 1) ^ + if ((self.state & 0x80) != 0) != ((input & input_mask) != 0) { + 0x07 /* x8 + x2 + x + 1 */ + } else { + 0 + }; + } } } } @@ -247,17 +254,17 @@ impl, NSS: OutputPin> Adc { fn write_reg(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError> { let address = reg.address(); - let checksum_out = match self.checksum_mode { - ChecksumMode::Off => None, - ChecksumMode::Xor => { - let mut xor = address; - for b in reg_data.as_mut() { - xor ^= *b; - } - Some(xor) - } - ChecksumMode::Crc => panic!("Not implemented"), - }; + let mut checksum = Checksum::new(match self.checksum_mode { + ChecksumMode::Off => ChecksumMode::Off, + // write checksums are always crc + ChecksumMode::Xor => ChecksumMode::Crc, + ChecksumMode::Crc => ChecksumMode::Crc, + }); + checksum.feed(address); + for &mut b in reg_data.as_mut() { + checksum.feed(b); + } + let checksum_out = checksum.result(); self.transfer(address, reg_data.as_mut(), checksum_out)?; Ok(()) } diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 6415e85..6706eaf 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -116,8 +116,8 @@ fn main() -> ! { writeln!(stdout, "Corrupt ADC id: {:04X}", id).unwrap(), }; } - writeln!(stdout, "AD7172: setting checksum mode to XOR").unwrap(); - adc.set_checksum_mode(ad7172::ChecksumMode::Xor).unwrap(); + writeln!(stdout, "AD7172: setting checksum mode").unwrap(); + adc.set_checksum_mode(ad7172::ChecksumMode::Crc).unwrap(); loop { let r = adc.identify(); match r {