use can_transport::{CanFrame, CanIoError};
use super::nmt::NmtState;
pub fn build_heartbeat_frame(hb_node_id: u8, state: NmtState) -> Result<CanFrame, CanIoError> {
let cob_id = 0x700u16 | (hb_node_id as u16 & 0x7F);
CanFrame::new_data(cob_id, &[state as u8])
}
pub fn encode_consumer_heartbeat_entry(producer_node_id: u8, timeout_ms: u16) -> u32 {
((producer_node_id as u32 & 0xFF) << 16) | (timeout_ms as u32)
}
#[cfg(test)]
mod tests {
use super::*;
use can_transport::CanId;
#[test]
fn hb_frame_format() {
let f = build_heartbeat_frame(0x10, NmtState::Operational).unwrap();
assert_eq!(f.id(), CanId::Standard(0x710));
assert_eq!(f.data(), &[0x05]);
}
#[test]
fn hb_frame_preop() {
let f = build_heartbeat_frame(0x10, NmtState::PreOperational).unwrap();
assert_eq!(f.data(), &[0x7F]);
}
#[test]
fn consumer_entry_typical() {
let e = encode_consumer_heartbeat_entry(0x10, 250);
assert_eq!(e, 0x0010_00FA);
}
#[test]
fn consumer_entry_disable() {
assert_eq!(encode_consumer_heartbeat_entry(0, 0), 0);
}
}