use embedded_hal::digital::OutputPin;
use embedded_hal_async::spi::SpiBus;
use super::cmd::cmd_system::*;
use super::{BusyPin, Lr2021, Lr2021Error};
#[derive(Default, Clone, Copy)]
pub struct FifoIrqEn(u8);
impl FifoIrqEn {
pub fn none() -> Self {
Self(0x00)
}
pub fn high_low() -> Self {
Self(0x06)
}
pub fn all() -> Self {
Self(0x3F)
}
pub fn value(&self) -> u8 {
self.0
}
pub fn with_empty(&self) -> Self {
Self(self.0 | 0x01)
}
pub fn with_low(&self) -> Self {
Self(self.0 | 0x02)
}
pub fn with_high(&self) -> Self {
Self(self.0 | 0x04)
}
pub fn with_full(&self) -> Self {
Self(self.0 | 0x08)
}
pub fn with_overflow(&self) -> Self {
Self(self.0 | 0x10)
}
pub fn with_underflow(&self) -> Self {
Self(self.0 | 0x20)
}
pub fn has_empty(&self) -> bool {
self.0 & 0x01 !=0
}
pub fn has_low(&self) -> bool {
self.0 & 0x02 !=0
}
pub fn has_high(&self) -> bool {
self.0 & 0x04 !=0
}
pub fn has_full(&self) -> bool {
self.0 & 0x08 !=0
}
pub fn has_overflow(&self) -> bool {
self.0 & 0x10 !=0
}
pub fn has_underflow(&self) -> bool {
self.0 & 0x20 !=0
}
}
#[derive(Default, Clone, Copy)]
pub struct FifoIrqCfg{
pub en: FifoIrqEn,
pub thr_low: u16,
pub thr_high: u16,
}
impl FifoIrqCfg {
pub fn new(en: FifoIrqEn, thr_low: u16, thr_high: u16) -> Self {
Self {en, thr_low, thr_high}
}
}
impl<O,SPI, M> Lr2021<O,SPI, M> where
O: OutputPin, SPI: SpiBus<u8>, M: BusyPin
{
pub async fn set_fifo_irq_en(&mut self, tx_en: FifoIrqEn, rx_en: FifoIrqEn) -> Result<(), Lr2021Error> {
let req = config_fifo_irq_cmd(rx_en.value(), tx_en.value());
self.cmd_wr(&req).await
}
pub async fn set_fifo_irq_cfg(&mut self, tx: FifoIrqCfg, rx: FifoIrqCfg) -> Result<(), Lr2021Error> {
let req = config_fifo_irq_adv_cmd(rx.en.value(), tx.en.value(), rx.thr_high, tx.thr_low, rx.thr_low, tx.thr_high);
self.cmd_wr(&req).await
}
pub async fn get_fifo_irq(&mut self) -> Result<(FifoIrqEn,FifoIrqEn), Lr2021Error> {
let req = get_fifo_irq_flags_req();
let mut rsp = FifoIrqFlagsRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
let tx_flags = FifoIrqEn(rsp.tx_fifo_flags());
let rx_flags = FifoIrqEn(rsp.rx_fifo_flags());
Ok((tx_flags,rx_flags))
}
pub async fn wr_tx_fifo_from(&mut self, buffer: &[u8]) -> Result<(), Lr2021Error> {
self.cmd_data_wr(&[0,2], buffer).await
}
pub async fn wr_tx_fifo(&mut self, len: usize) -> Result<(), Lr2021Error> {
self.cmd_wr_begin(&[0,2]).await?;
self.spi
.transfer_in_place(&mut self.buffer.data_mut()[..len]).await
.map_err(|_| Lr2021Error::Spi)?;
self.nss.set_high().map_err(|_| Lr2021Error::Pin)
}
pub async fn clear_tx_fifo(&mut self) -> Result<(), Lr2021Error> {
self.cmd_wr(&clear_tx_fifo_cmd()).await
}
pub async fn get_tx_fifo_lvl(&mut self) -> Result<u16, Lr2021Error> {
let req = get_tx_fifo_level_req();
let mut rsp = TxFifoLevelRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp.level())
}
pub async fn rd_rx_fifo_to(&mut self, buffer: &mut[u8]) -> Result<(), Lr2021Error> {
self.cmd_data_rw(&[0,1], buffer).await
}
pub async fn rd_rx_fifo(&mut self, len: usize) -> Result<(), Lr2021Error> {
self.cmd_wr_begin(&[0,1]).await?;
self.spi
.transfer_in_place(&mut self.buffer.data_mut()[..len]).await
.map_err(|_| Lr2021Error::Spi)?;
self.nss.set_high().map_err(|_| Lr2021Error::Pin)
}
pub async fn get_rx_fifo_lvl(&mut self) -> Result<u16, Lr2021Error> {
let req = get_rx_fifo_level_req();
let mut rsp = RxFifoLevelRsp::new();
self.cmd_rd(&req, rsp.as_mut()).await?;
Ok(rsp.level())
}
pub async fn clear_rx_fifo(&mut self) -> Result<(), Lr2021Error> {
self.cmd_wr(&clear_rx_fifo_cmd()).await
}
}