ad7172::checksum: improve

This commit is contained in:
Astro 2020-03-12 00:43:11 +01:00
parent 95d66438d2
commit 44c8ff54c1
3 changed files with 33 additions and 14 deletions

View File

@ -134,12 +134,12 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
let mut reg_data = R::Data::empty(); let mut reg_data = R::Data::empty();
let address = 0x40 | reg.address(); let address = 0x40 | reg.address();
let mut checksum = Checksum::new(self.checksum_mode); let mut checksum = Checksum::new(self.checksum_mode);
checksum.feed(address); checksum.feed(&[address]);
let checksum_out = checksum.result(); let checksum_out = checksum.result();
let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?; let checksum_in = self.transfer(address, reg_data.as_mut(), checksum_out)?;
for &mut b in reg_data.as_mut() {
checksum.feed(b); checksum.feed(&reg_data);
}
let checksum_expected = checksum.result(); let checksum_expected = checksum.result();
if checksum_expected != checksum_in { if checksum_expected != checksum_in {
return Err(AdcError::ChecksumMismatch(checksum_expected, checksum_in)); return Err(AdcError::ChecksumMismatch(checksum_expected, checksum_in));
@ -155,10 +155,8 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
ChecksumMode::Xor => ChecksumMode::Crc, ChecksumMode::Xor => ChecksumMode::Crc,
ChecksumMode::Crc => ChecksumMode::Crc, ChecksumMode::Crc => ChecksumMode::Crc,
}); });
checksum.feed(address); checksum.feed(&[address]);
for &mut b in reg_data.as_mut() { checksum.feed(&reg_data);
checksum.feed(b);
}
let checksum_out = checksum.result(); let checksum_out = checksum.result();
self.transfer(address, reg_data.as_mut(), checksum_out)?; self.transfer(address, reg_data.as_mut(), checksum_out)?;
Ok(()) Ok(())

View File

@ -27,7 +27,7 @@ impl Checksum {
Checksum { mode, state: 0 } Checksum { mode, state: 0 }
} }
pub fn feed(&mut self, input: u8) { fn feed_byte(&mut self, input: u8) {
match self.mode { match self.mode {
ChecksumMode::Off => {}, ChecksumMode::Off => {},
ChecksumMode::Xor => self.state ^= input, ChecksumMode::Xor => self.state ^= input,
@ -45,6 +45,12 @@ impl Checksum {
} }
} }
pub fn feed(&mut self, input: &[u8]) {
for &b in input {
self.feed_byte(b);
}
}
pub fn result(&self) -> Option<u8> { pub fn result(&self) -> Option<u8> {
match self.mode { match self.mode {
ChecksumMode::Off => None, ChecksumMode::Off => None,

View File

@ -1,3 +1,4 @@
use core::ops::{Deref, DerefMut};
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use bit_field::BitField; use bit_field::BitField;
@ -7,9 +8,8 @@ pub trait Register {
type Data: RegisterData; type Data: RegisterData;
fn address(&self) -> u8; fn address(&self) -> u8;
} }
pub trait RegisterData { pub trait RegisterData: Deref<Target=[u8]> + DerefMut {
fn empty() -> Self; fn empty() -> Self;
fn as_mut(&mut self) -> &mut [u8];
} }
macro_rules! def_reg { macro_rules! def_reg {
@ -32,8 +32,15 @@ macro_rules! def_reg {
fn empty() -> Self { fn empty() -> Self {
Data([0; $size]) Data([0; $size])
} }
/// Borrow for SPI transfer }
fn as_mut(&mut self) -> &mut [u8] { impl core::ops::Deref for Data {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl core::ops::DerefMut for Data {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.0 &mut self.0
} }
} }
@ -53,7 +60,15 @@ macro_rules! def_reg {
fn empty() -> Self { fn empty() -> Self {
Data([0; $size]) Data([0; $size])
} }
fn as_mut(&mut self) -> &mut [u8] { }
impl core::ops::Deref for Data {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl core::ops::DerefMut for Data {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.0 &mut self.0
} }
} }