#![allow(
non_camel_case_types,
non_upper_case_globals,
non_snake_case,
dead_code
)]
include!("generator/nican.rs");
use crate::NiCanFrame;
use rs_can::{CanDirection, CanError, CanFrame, CanId, Timestamp, TimestampSource, MAX_FRAME_SIZE};
impl Into<NCTYPE_CAN_FRAME> for NiCanFrame {
fn into(self) -> NCTYPE_CAN_FRAME {
let mut arb_id = self.id().as_raw();
if self.is_extended() {
arb_id |= NC_FL_CAN_ARBID_XTD;
}
let data_len = self.data().len() as u8;
let mut data = self.data().to_vec();
if data.len() < MAX_FRAME_SIZE {
data.resize(MAX_FRAME_SIZE, Default::default());
}
NCTYPE_CAN_FRAME {
ArbitrationId: arb_id as NCTYPE_CAN_ARBID,
IsRemote: if self.is_remote() { 1 } else { 0 },
DataLength: data_len,
Data: data.try_into().unwrap(),
}
}
}
impl TryInto<NiCanFrame> for NCTYPE_CAN_STRUCT {
type Error = CanError;
fn try_into(self) -> Result<NiCanFrame, Self::Error> {
let is_remote_frame = self.FrameType == NC_FRMTYPE_REMOTE as u8;
let is_error_frame = self.FrameType == NC_FRMTYPE_COMM_ERR as u8;
let arb_id = self.ArbitrationId as u32;
let is_extended = (arb_id & NC_FL_CAN_ARBID_XTD) > 0;
let dlc = self.DataLength;
let timestamp = (self.Timestamp.HighPart as u64) << 32 | (self.Timestamp.LowPart as u64);
if is_error_frame {
return Err(CanError::InvalidFrame(
"NI-CAN communication error frame is not supported by NiCanFrame".into(),
));
}
let id = CanId::from_bits(arb_id, Some(is_extended))?;
let mut msg = if is_remote_frame {
NiCanFrame::new_remote(id, dlc)
} else {
NiCanFrame::new_can(id, &self.Data[..dlc as usize])
}
.map_err(|_| {
CanError::InvalidFrame(format!("length of data is rather than {}", MAX_FRAME_SIZE))
})?;
let filetime_100ns: u128 = timestamp as u128;
let epoch_diff_100ns: u128 = 11_644_473_600u128 * 10_000_000u128;
let nanos = filetime_100ns.saturating_sub(epoch_diff_100ns) * 100u128;
msg.set_direction(CanDirection::Receive)
.set_timestamp(Some(Timestamp {
nanos,
source: TimestampSource::Hardware,
}));
Ok(msg)
}
}