forked from M-Labs/thermostat
ad7172: readback after write_reg()
This commit is contained in:
parent
4c3c8498e9
commit
194871c85a
|
@ -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(®s::AdcMode, &mut adc_mode);
|
adc.write_reg(®s::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(®s::Offset { index }, &mut offset);
|
self.write_reg(®s::Offset { index }, &mut offset)?;
|
||||||
self.update_reg(®s::Channel { index }, |data| {
|
self.update_reg(®s::Channel { index }, |data| {
|
||||||
data.set_setup(index);
|
data.set_setup(index);
|
||||||
data.set_enabled(true);
|
data.set_enabled(true);
|
||||||
|
@ -154,30 +154,33 @@ 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>> {
|
||||||
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 {
|
loop {
|
||||||
let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?;
|
let address = reg.address();
|
||||||
if checksum_in.unwrap_or(0) == 0 {
|
let mut checksum = Checksum::new(match self.checksum_mode {
|
||||||
break;
|
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<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>>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue