Skip to content

Commit

Permalink
Merge pull request #18 from atlas-aero/17-add-support-for-different-c…
Browse files Browse the repository at this point in the history
…an-data-bytes-lengths

17 add support for different can data bytes lengths
  • Loading branch information
marius-meissner authored Sep 9, 2024
2 parents f476e58 + c58c198 commit 206ce3d
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 30 deletions.
2 changes: 1 addition & 1 deletion example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ fn main() -> ! {
let _ = can_controller.set_filter_object(filter);

// Create message frame
let message_type = Can20 {};
let message_type = Can20::<8> {};
let payload = [1, 2, 3, 4, 5, 6, 7, 8];
let pl_bytes = Bytes::copy_from_slice(&payload);
let can_message = TxMessage::new(message_type, pl_bytes, can_id).unwrap();
Expand Down
50 changes: 28 additions & 22 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,38 +96,49 @@ pub struct TxHeader {
pub data_length_code: DLC,
}

/// CAN 2.0 message type
#[derive(Debug, Copy, Clone)]
pub struct Can20 {}
pub trait MessageType<const L: usize> {
/// Setup CAN message header depending on message type
fn setup_header(&self, header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError>;
}

impl MessageType<8> for Can20 {
fn setup_header(&self, _header: &mut TxHeader) -> Result<(), DLCError> {
/// CAN 2.0 message type where L is the number // if payload_length > MAX_LENGTH {
#[derive(Debug, Copy, Clone)]
pub struct Can20<const L: usize> {}

impl<const L: usize> MessageType<L> for Can20<L> {
fn setup_header(&self, _header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError> {
if L > 8 || payload_length > 8 {
let max = payload_length.max(L);
debug!("Maximum of 8 bytes allowed. Current size: {max} bytes");
return Err(DLCError::InvalidLength(max));
}
Ok(())
}
}

/// CAN FD message type
/// CAN FD message type where L is number data bytes
#[derive(Debug, Copy, Clone)]
pub struct CanFd {
pub struct CanFd<const L: usize> {
pub bitrate_switch: bool,
}

impl MessageType<64> for CanFd {
fn setup_header(&self, header: &mut TxHeader) -> Result<(), DLCError> {
impl<const L: usize> MessageType<L> for CanFd<L> {
fn setup_header(&self, header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError> {
if L > 64 || payload_length > 64 {
let max = payload_length.max(L);
debug!("Maximum of 64 bytes allowed. Current size: {max} bytes");
return Err(DLCError::InvalidLength(max));
}

header.set_bit_rate_switch(self.bitrate_switch);
header.set_fd_frame(true);
Ok(())
}
}

pub trait MessageType<const MAX_LENGTH: usize> {
/// Setup CAN message header depending on message type
fn setup_header(&self, header: &mut TxHeader) -> Result<(), DLCError>;
}

/// Transmit Message Object
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct TxMessage<T, const MAX_LENGTH: usize> {
pub struct TxMessage<T: MessageType<L>, const L: usize> {
/// first 2 bytes of Transmit Message Object
pub(crate) header: TxHeader,
/// Payload bytes of Message Object
Expand All @@ -136,18 +147,13 @@ pub struct TxMessage<T, const MAX_LENGTH: usize> {
pub(crate) message_type: T,
}

impl<T: MessageType<MAX_LENGTH>, const MAX_LENGTH: usize> TxMessage<T, MAX_LENGTH> {
impl<T: MessageType<L>, const L: usize> TxMessage<T, L> {
pub fn new(message_type: T, data: Bytes, identifier: Id) -> Result<Self, DLCError> {
let mut header = TxHeader::new();

let mut payload_length = data.len();

if payload_length > MAX_LENGTH {
debug!("Maximum of {MAX_LENGTH} bytes allowed. Current size: {payload_length} bytes");
return Err(DLCError::InvalidLength(payload_length));
}

message_type.setup_header(&mut header)?;
message_type.setup_header(&mut header, payload_length)?;

// length used to choose the next supported DLC
while let Err(DLCError::InvalidLength(_)) = DLC::from_length(payload_length) {
Expand Down
4 changes: 2 additions & 2 deletions src/tests/can.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ fn test_transmit_can20() {
let payload: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
let payload_bytes = Bytes::copy_from_slice(&payload);

let msg_type = Can20 {};
let msg_type = Can20::<8> {};

let identifier = ExtendedId::new(EXTENDED_ID).unwrap();
let tx_message = TxMessage::new(msg_type, payload_bytes, Id::Extended(identifier)).unwrap();
Expand Down Expand Up @@ -285,7 +285,7 @@ fn test_transmit_can_fd() {
let payload = [1u8; 64];
let payload_bytes = Bytes::copy_from_slice(&payload);

let msg_type = CanFd { bitrate_switch: false };
let msg_type = CanFd::<64> { bitrate_switch: false };

let identifier = ExtendedId::new(EXTENDED_ID).unwrap();
let tx_message = TxMessage::new(msg_type, payload_bytes, Id::Extended(identifier)).unwrap();
Expand Down
10 changes: 5 additions & 5 deletions src/tests/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn test_extended_id() {
let payload_bytes = Bytes::copy_from_slice(&[0u8; 8]);
let extended_id = ExtendedId::new(EXTENDED_ID).unwrap();

let msg_type = Can20 {};
let msg_type = Can20::<8> {};

let message = TxMessage::new(msg_type, payload_bytes, Id::Extended(extended_id)).unwrap();

Expand All @@ -26,7 +26,7 @@ fn test_standard_id() {
let payload_bytes = Bytes::copy_from_slice(&[0u8; 8]);
let standard_id = StandardId::new(STANDARD_ID).unwrap();

let msg_type = Can20 {};
let msg_type = Can20::<8> {};

let message = TxMessage::new(msg_type, payload_bytes, Id::Standard(standard_id)).unwrap();

Expand All @@ -40,7 +40,7 @@ fn test_dlc_success() {
let payload_bytes = Bytes::copy_from_slice(&[0u8; 13]);
let standard_id = StandardId::new(STANDARD_ID).unwrap();

let msg_type = CanFd { bitrate_switch: false };
let msg_type = CanFd::<13> { bitrate_switch: false };

let message = TxMessage::new(msg_type, payload_bytes, Id::Standard(standard_id)).unwrap();

Expand All @@ -60,8 +60,8 @@ fn test_dlc_error() {
let payload_bytes_2_0 = Bytes::copy_from_slice(&data_2_0);
let payload_bytes_fd = Bytes::copy_from_slice(&data_fd);

let can_msg_20 = Can20 {};
let can_msg_fd = CanFd { bitrate_switch: false };
let can_msg_20 = Can20::<8> {};
let can_msg_fd = CanFd::<64> { bitrate_switch: false };

let standard_id = StandardId::new(STANDARD_ID).unwrap();

Expand Down

0 comments on commit 206ce3d

Please sign in to comment.