ad7172: readback after write_reg()

This commit is contained in:
Astro 2020-03-20 23:19:31 +01:00
parent 4c3c8498e9
commit 194871c85a
2 changed files with 25 additions and 19 deletions

View File

@ -42,7 +42,7 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
let mut adc_mode = <regs::AdcMode as Register>::Data::empty(); let mut adc_mode = <regs::AdcMode as Register>::Data::empty();
adc_mode.set_ref_en(true); adc_mode.set_ref_en(true);
adc.write_reg(&regs::AdcMode, &mut adc_mode); adc.write_reg(&regs::AdcMode, &mut adc_mode)?;
Ok(adc) Ok(adc)
} }
@ -87,7 +87,7 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
})?; })?;
let mut offset = <regs::Offset as regs::Register>::Data::empty(); let mut offset = <regs::Offset as regs::Register>::Data::empty();
offset.set_offset(0); offset.set_offset(0);
self.write_reg(&regs::Offset { index }, &mut offset); self.write_reg(&regs::Offset { index }, &mut offset)?;
self.update_reg(&regs::Channel { index }, |data| { self.update_reg(&regs::Channel { index }, |data| {
data.set_setup(index); data.set_setup(index);
data.set_enabled(true); data.set_enabled(true);
@ -154,12 +154,13 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
break; break;
} }
// Retry // Retry
warn!("read_reg checksum error, retrying"); warn!("read_reg {:02X}: checksum error: {:?}!={:?}, retrying", reg.address(), checksum_expected, checksum_in);
} }
Ok(reg_data) Ok(reg_data)
} }
fn write_reg<R: regs::Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> { fn write_reg<R: regs::Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
loop {
let address = reg.address(); let address = reg.address();
let mut checksum = Checksum::new(match self.checksum_mode { let mut checksum = Checksum::new(match self.checksum_mode {
ChecksumMode::Off => ChecksumMode::Off, ChecksumMode::Off => ChecksumMode::Off,
@ -170,14 +171,16 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
checksum.feed(&[address]); checksum.feed(&[address]);
checksum.feed(&reg_data); checksum.feed(&reg_data);
let checksum_out = checksum.result(); let checksum_out = checksum.result();
loop {
let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?; let mut data = reg_data.clone();
if checksum_in.unwrap_or(0) == 0 { let checksum_in = self.transfer(address, data.as_mut(), checksum_out)?;
break;
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<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>> fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>

View File

@ -8,7 +8,8 @@ pub trait Register {
type Data: RegisterData; type Data: RegisterData;
fn address(&self) -> u8; fn address(&self) -> u8;
} }
pub trait RegisterData: Deref<Target=[u8]> + DerefMut {
pub trait RegisterData: Clone + Deref<Target=[u8]> + DerefMut {
fn empty() -> Self; fn empty() -> Self;
} }
@ -26,6 +27,7 @@ macro_rules! def_reg {
} }
mod $reg { mod $reg {
/// Register contents /// Register contents
#[derive(Clone)]
pub struct Data(pub [u8; $size]); pub struct Data(pub [u8; $size]);
impl super::RegisterData for Data { impl super::RegisterData for Data {
/// Generate zeroed register contents /// Generate zeroed register contents
@ -55,6 +57,7 @@ macro_rules! def_reg {
} }
} }
mod $reg { mod $reg {
#[derive(Clone)]
pub struct Data(pub [u8; $size]); pub struct Data(pub [u8; $size]);
impl super::RegisterData for Data { impl super::RegisterData for Data {
fn empty() -> Self { fn empty() -> Self {