diff --git a/src/ad7172/adc.rs b/src/ad7172/adc.rs index 8b92ae6..ec1a6dc 100644 --- a/src/ad7172/adc.rs +++ b/src/ad7172/adc.rs @@ -42,7 +42,7 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc let mut adc_mode = ::Data::empty(); adc_mode.set_ref_en(true); - adc.write_reg(®s::AdcMode, &mut adc_mode); + adc.write_reg(®s::AdcMode, &mut adc_mode)?; Ok(adc) } @@ -87,7 +87,7 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc })?; let mut offset = ::Data::empty(); offset.set_offset(0); - self.write_reg(®s::Offset { index }, &mut offset); + self.write_reg(®s::Offset { index }, &mut offset)?; self.update_reg(®s::Channel { index }, |data| { data.set_setup(index); data.set_enabled(true); @@ -154,30 +154,33 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc break; } // Retry - warn!("read_reg checksum error, retrying"); + warn!("read_reg {:02X}: checksum error: {:?}!={:?}, retrying", reg.address(), checksum_expected, checksum_in); } Ok(reg_data) } fn write_reg(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError> { - let address = reg.address(); - 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]); - checksum.feed(®_data); - let checksum_out = checksum.result(); loop { - let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?; - if checksum_in.unwrap_or(0) == 0 { - break; + let address = reg.address(); + 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]); + checksum.feed(®_data); + let checksum_out = checksum.result(); + + let mut data = reg_data.clone(); + let checksum_in = self.transfer(address, data.as_mut(), checksum_out)?; + + let readback_data = self.read_reg(reg)?; + if *readback_data == **reg_data { + return Ok(()); } - warn!("write_reg: checksum={:02X}, retrying", checksum_in.unwrap_or(0)); + warn!("write_reg {:02X}: readback error, {:?}!={:?}, retrying", address, &*readback_data, &**reg_data); } - Ok(()) } fn update_reg(&mut self, reg: &R, f: F) -> Result> diff --git a/src/ad7172/regs.rs b/src/ad7172/regs.rs index b0f989f..5f730d5 100644 --- a/src/ad7172/regs.rs +++ b/src/ad7172/regs.rs @@ -8,7 +8,8 @@ pub trait Register { type Data: RegisterData; fn address(&self) -> u8; } -pub trait RegisterData: Deref + DerefMut { + +pub trait RegisterData: Clone + Deref + DerefMut { fn empty() -> Self; } @@ -26,6 +27,7 @@ macro_rules! def_reg { } mod $reg { /// Register contents + #[derive(Clone)] pub struct Data(pub [u8; $size]); impl super::RegisterData for Data { /// Generate zeroed register contents @@ -55,6 +57,7 @@ macro_rules! def_reg { } } mod $reg { + #[derive(Clone)] pub struct Data(pub [u8; $size]); impl super::RegisterData for Data { fn empty() -> Self {