use embedded_hal;
use super::SensorInterface;
use crate::interface::{SensorCommon, PACKET_HEADER_LENGTH};
use embedded_hal::blocking::delay::DelayMs;
use embedded_hal::digital::v2::{InputPin, OutputPin};
use crate::Error;
use crate::Error::SensorUnresponsive;
#[cfg(feature = "rttdebug")]
use panic_rtt_core::rprintln;
pub struct SpiControlLines<SPI, CSN, IN, RSTN> {
pub spi: SPI,
pub csn: CSN,
pub hintn: IN,
pub reset: RSTN,
}
pub struct SpiInterface<SPI, CSN, IN, RSTN> {
spi: SPI,
csn: CSN,
hintn: IN,
reset: RSTN,
received_packet_count: usize,
}
impl<SPI, CSN, IN, RSTN, CommE, PinE> SpiInterface<SPI, CSN, IN, RSTN>
where
SPI: embedded_hal::blocking::spi::Write<u8, Error = CommE>
+ embedded_hal::blocking::spi::Transfer<u8, Error = CommE>,
CSN: OutputPin<Error = PinE>,
IN: InputPin<Error = PinE>,
RSTN: OutputPin<Error = PinE>,
CommE: core::fmt::Debug,
PinE: core::fmt::Debug,
{
pub fn new(lines: SpiControlLines<SPI, CSN, IN, RSTN>) -> Self {
Self {
spi: lines.spi,
csn: lines.csn,
hintn: lines.hintn,
reset: lines.reset,
received_packet_count: 0,
}
}
fn hintn_signaled(&self) -> bool {
self.hintn.is_low().unwrap_or(false)
}
fn wait_for_sensor_awake(
&mut self,
delay_source: &mut impl DelayMs<u8>,
max_ms: u8,
) -> bool {
for _ in 0..max_ms {
if self.hintn_signaled() {
return true;
}
delay_source.delay_ms(1);
}
false
}
fn block_on_hintn(&mut self, max_cycles: usize) -> bool {
for _ in 0..max_cycles {
if self.hintn_signaled() {
return true;
}
}
#[cfg(feature = "rttdebug")]
rprintln!("no hintn??");
false
}
fn read_packet_cargo(&mut self, recv_buf: &mut [u8]) -> usize {
let mut packet_len = SensorCommon::parse_packet_header(
&recv_buf[..PACKET_HEADER_LENGTH],
);
if (packet_len > PACKET_HEADER_LENGTH) && (packet_len < recv_buf.len())
{
for w in recv_buf[PACKET_HEADER_LENGTH..packet_len].iter_mut() {
*w = 0xFF;
}
let rc = self
.spi
.transfer(&mut recv_buf[PACKET_HEADER_LENGTH..packet_len]);
if rc.is_err() {
packet_len = 0;
}
} else {
packet_len = 0;
}
packet_len
}
}
impl<SPI, CSN, IN, RS, CommE, PinE> SensorInterface
for SpiInterface<SPI, CSN, IN, RS>
where
SPI: embedded_hal::blocking::spi::Write<u8, Error = CommE>
+ embedded_hal::blocking::spi::Transfer<u8, Error = CommE>,
CSN: OutputPin<Error = PinE>,
IN: InputPin<Error = PinE>,
RS: OutputPin<Error = PinE>,
CommE: core::fmt::Debug,
PinE: core::fmt::Debug,
{
type SensorError = Error<CommE, PinE>;
fn requires_soft_reset(&self) -> bool {
false
}
fn setup(
&mut self,
delay_source: &mut impl DelayMs<u8>,
) -> Result<(), Self::SensorError> {
self.csn.set_high().map_err(Error::Pin)?;
self.reset.set_high().map_err(Error::Pin)?;
self.reset.set_low().map_err(Error::Pin)?;
delay_source.delay_ms(2);
self.reset.set_high().map_err(Error::Pin)?;
let ready = self.wait_for_sensor_awake(delay_source, 200u8);
if !ready {
#[cfg(feature = "rttdebug")]
rprintln!("sensor not ready");
return Err(SensorUnresponsive);
}
Ok(())
}
fn send_and_receive_packet(
&mut self,
send_buf: &[u8],
recv_buf: &mut [u8],
) -> Result<usize, Self::SensorError> {
self.csn.set_low().map_err(Error::Pin)?;
let rc = self.spi.write(&send_buf).map_err(Error::Comm);
self.csn.set_high().map_err(Error::Pin)?;
if rc.is_err() {
return Err(rc.unwrap_err());
}
#[cfg(feature = "rttdebug")]
rprintln!("sent {}", send_buf.len());
for i in recv_buf[..PACKET_HEADER_LENGTH].iter_mut() {
*i = 0;
}
if !self.block_on_hintn(1000) {
#[cfg(feature = "rttdebug")]
rprintln!("no packet to read?");
return Ok(0);
}
self.csn.set_low().map_err(Error::Pin)?;
let rc = self
.spi
.transfer(&mut recv_buf[..PACKET_HEADER_LENGTH])
.map_err(Error::Comm);
if rc.is_err() {
#[cfg(feature = "rttdebug")]
rprintln!("transfer err: {:?}", rc);
self.csn.set_high().map_err(Error::Pin)?;
return Err(rc.unwrap_err());
}
let packet_len = self.read_packet_cargo(recv_buf);
self.csn.set_high().map_err(Error::Pin)?;
if packet_len > 0 {
self.received_packet_count += 1;
}
Ok(packet_len)
}
fn write_packet(&mut self, packet: &[u8]) -> Result<(), Self::SensorError> {
self.csn.set_low().map_err(Error::Pin)?;
let rc = self.spi.write(&packet).map_err(Error::Comm);
self.csn.set_high().map_err(Error::Pin)?;
if rc.is_err() {
return Err(rc.unwrap_err());
}
Ok(())
}
fn read_packet(
&mut self,
recv_buf: &mut [u8],
) -> Result<usize, Self::SensorError> {
for i in recv_buf[..PACKET_HEADER_LENGTH].iter_mut() {
*i = 0;
}
self.csn.set_low().map_err(Error::Pin)?;
let rc = self
.spi
.transfer(&mut recv_buf[..PACKET_HEADER_LENGTH])
.map_err(Error::Comm);
if rc.is_err() {
self.csn.set_high().map_err(Error::Pin)?;
return Err(rc.unwrap_err());
}
let packet_len = self.read_packet_cargo(recv_buf);
self.csn.set_high().map_err(Error::Pin)?;
if packet_len > 0 {
self.received_packet_count += 1;
}
Ok(packet_len)
}
fn read_with_timeout(
&mut self,
recv_buf: &mut [u8],
delay_source: &mut impl DelayMs<u8>,
max_ms: u8,
) -> Result<usize, Self::SensorError> {
if self.wait_for_sensor_awake(delay_source, max_ms) {
return self.read_packet(recv_buf);
}
Ok(0)
}
}