forked from M-Labs/thermostat
ad7172::checksum: improve
This commit is contained in:
parent
95d66438d2
commit
44c8ff54c1
|
@ -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(®_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(®_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(())
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue