use core::fmt::Debug;
use embedded_hal::can::{ExtendedId, Frame, Id, StandardId};
use modular_bitfield::prelude::*;
use crate::{
error::{Error, Result},
frame::CanFrame,
regs::Register,
};
#[bitfield]
#[derive(Debug, Clone, Copy, PartialEq, Eq, BitfieldSpecifier)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
pub struct TxBufIdent {
pub dlc: B4,
#[skip]
__: B2,
pub rtr: bool,
#[skip]
__: B1,
pub eid: B18,
#[skip]
__: B1,
pub exide: bool,
#[skip]
__: B1,
pub sid: B11,
}
impl TxBufIdent {
pub fn from_frame(frame: &CanFrame) -> Self {
let mut reg = TxBufIdent::new()
.with_dlc(frame.dlc() as u8)
.with_rtr(frame.is_remote_frame());
match &frame.id() {
Id::Standard(id) => {
reg.set_exide(false);
reg.set_sid(id.as_raw());
}
Id::Extended(id) => {
reg.set_exide(true);
reg.set_eid(id.as_raw() & 0x3FFFF); reg.set_sid((id.as_raw() >> 18) as u16); }
};
reg
}
}
crate::filter_def! {
TxBuf(5) => {
B0 => [Register::TXB0DLC, Register::TXB0EID0, Register::TXB0EID8, Register::TXB0SIDL, Register::TXB0SIDH],
B1 => [Register::TXB1DLC, Register::TXB1EID0, Register::TXB1EID8, Register::TXB1SIDL, Register::TXB1SIDH],
B2 => [Register::TXB2DLC, Register::TXB2EID0, Register::TXB2EID8, Register::TXB2SIDL, Register::TXB2SIDH]
}
}
impl TxBuf {
pub const fn ctrl(self) -> Register {
match self {
TxBuf::B0 => Register::TXB0CTRL,
TxBuf::B1 => Register::TXB1CTRL,
TxBuf::B2 => Register::TXB2CTRL,
}
}
pub const fn data(self) -> Register {
match self {
TxBuf::B0 => Register::TXB0DATA,
TxBuf::B1 => Register::TXB1DATA,
TxBuf::B2 => Register::TXB2DATA,
}
}
}
#[bitfield]
#[derive(Debug, Clone, Copy, PartialEq, Eq, BitfieldSpecifier)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
pub struct RxBufIdent {
pub dlc: B4,
#[skip]
__: B2,
pub rtr: bool,
#[skip]
__: B1,
pub eid: B18,
#[skip]
__: B1,
pub ide: bool,
pub srr: bool,
pub sid: B11,
}
impl RxBufIdent {
pub fn into_frame<SPIE: Debug, HALE: Debug>(
self,
read_data: impl FnOnce(&mut [u8]) -> Result<(), SPIE, HALE>,
) -> Result<CanFrame, SPIE, HALE> {
let id = if self.ide() {
let id = self.eid() | ((self.sid() as u32) << 18);
Id::Extended(ExtendedId::new(id).ok_or(Error::InvalidFrameId)?)
} else {
Id::Standard(StandardId::new(self.sid()).ok_or(Error::InvalidFrameId)?)
};
let dlc = self.dlc();
if dlc > 8 {
return Err(Error::InvalidDlc);
}
let mut frame = CanFrame {
id,
rtr: self.srr() && !self.ide(),
dlc,
data: [0; 8],
};
read_data(&mut frame.data[..(dlc as usize)])?;
Ok(frame)
}
}
crate::filter_def! {
RxBuf(5) => {
B0 => [Register::RXB0DLC, Register::RXB0EID0, Register::RXB0EID8, Register::RXB0SIDL, Register::RXB0SIDH],
B1 => [Register::RXB1DLC, Register::RXB1EID0, Register::RXB1EID8, Register::RXB1SIDL, Register::RXB1SIDH]
}
}
impl RxBuf {
pub const fn ctrl(self) -> Register {
match self {
RxBuf::B0 => Register::RXB0CTRL,
RxBuf::B1 => Register::RXB1CTRL,
}
}
pub const fn data(self) -> Register {
match self {
RxBuf::B0 => Register::RXB0DATA,
RxBuf::B1 => Register::RXB1DATA,
}
}
}