pub mod i2c;
pub mod spi;
#[cfg(test)]
pub mod mock_i2c_port;
use core::ops::Shl;
use embedded_hal::blocking::delay::DelayMs;
#[cfg(feature = "rttdebug")]
use panic_rtt_core::rprintln;
pub trait SensorInterface {
type SensorError;
fn setup(
&mut self,
delay_source: &mut impl DelayMs<u8>,
) -> Result<(), Self::SensorError>;
fn write_packet(&mut self, packet: &[u8]) -> Result<(), Self::SensorError>;
fn read_packet(
&mut self,
recv_buf: &mut [u8],
) -> Result<usize, Self::SensorError>;
fn read_with_timeout(
&mut self,
recv_buf: &mut [u8],
delay_source: &mut impl DelayMs<u8>,
max_ms: u8,
) -> Result<usize, Self::SensorError>;
fn send_and_receive_packet(
&mut self,
send_buf: &[u8],
recv_buf: &mut [u8],
) -> Result<usize, Self::SensorError>;
fn requires_soft_reset(&self) -> bool;
}
pub use self::i2c::I2cInterface;
pub use self::spi::SpiInterface;
pub(crate) const PACKET_HEADER_LENGTH: usize = 4;
pub(crate) const MAX_CARGO_DATA_LENGTH: usize = 32766 - PACKET_HEADER_LENGTH;
struct SensorCommon {}
impl SensorCommon {
fn parse_packet_header(packet: &[u8]) -> usize {
const CONTINUATION_FLAG_MASK: u16 = 0x80;
const CONTINUATION_FLAG_CLEAR: u16 = !(CONTINUATION_FLAG_MASK);
if packet.len() < PACKET_HEADER_LENGTH {
return 0;
}
let raw_pack_len: u16 = (packet[0] as u16)
+ ((packet[1] as u16) & CONTINUATION_FLAG_CLEAR).shl(8);
let mut packet_len: usize = raw_pack_len as usize;
if packet_len > MAX_CARGO_DATA_LENGTH {
packet_len = 0; }
if 0 == packet_len && 0 != raw_pack_len {
#[cfg(feature = "rttdebug")]
rprintln!(
"pph: {:?} {} -> {}",
&packet[..PACKET_HEADER_LENGTH],
raw_pack_len,
packet_len
);
} else {
}
packet_len
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::ops::Shr;
#[test]
fn test_parse_packet_header() {
let short_packet: [u8; 2] = [13, 15];
let size = SensorCommon::parse_packet_header(&short_packet);
assert_eq!(0, size, "truncated packet header should have length zero");
let long_packet_len: usize = 1024;
let mut raw_packet: [u8; PACKET_HEADER_LENGTH] = [
(long_packet_len & 0xFF) as u8,
long_packet_len.shr(8) as u8,
0,
0,
];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, long_packet_len, "verify > 255 packet length");
raw_packet[1] = 0x80 | raw_packet[1];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, long_packet_len, "verify continuation packet");
let short_packet_len: usize = 36;
raw_packet = [
(short_packet_len & 0xFF) as u8,
short_packet_len.shr(8) as u8,
0,
0,
];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, short_packet_len, "verify short packet");
raw_packet[1] = 0x80 | raw_packet[1];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, short_packet_len, "verify short packet continuation");
raw_packet = [20 as u8, 1 as u8, 0, 0];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, 276, "verify > 255 packet length");
raw_packet = [19 as u8, 129 as u8, 0, 1];
let size = SensorCommon::parse_packet_header(&raw_packet);
assert_eq!(size, 275, "verify > 255 packet length");
}
}