diff --git a/embassy-stm32/src/can/enums.rs b/embassy-stm32/src/can/enums.rs index a5cca424db..361b71e784 100644 --- a/embassy-stm32/src/can/enums.rs +++ b/embassy-stm32/src/can/enums.rs @@ -59,6 +59,14 @@ pub enum FrameCreateError { InvalidCanId, } +/// Id Create Errors +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum IdCreateError { + /// ID was out of range for 11/28 bit identifier + OutOfRange, +} + /// Error returned by `try_read` #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] diff --git a/embassy-stm32/src/can/frame.rs b/embassy-stm32/src/can/frame.rs index d2d1f7aa6d..9c612709a2 100644 --- a/embassy-stm32/src/can/frame.rs +++ b/embassy-stm32/src/can/frame.rs @@ -1,7 +1,7 @@ //! Definition for CAN Frames use bit_field::BitField; -use crate::can::enums::FrameCreateError; +use crate::can::enums::{FrameCreateError, IdCreateError}; /// Calculate proper timestamp when available. #[cfg(feature = "time")] @@ -19,6 +19,37 @@ pub struct Header { flags: u8, } +/// Convenience wrapper for embedded_can::Id +#[derive(Debug, Copy, Clone)] +pub struct Id( + // Wrapped ID + embedded_can::Id, +); + +impl TryFrom for Id { + type Error = IdCreateError; + + fn try_from(raw_id: u16) -> Result { + let standard_id = embedded_can::StandardId::new(raw_id).ok_or(IdCreateError::OutOfRange)?; + Ok(Id { 0: standard_id.into() }) + } +} + +impl TryFrom for Id { + type Error = IdCreateError; + + fn try_from(raw_id: u32) -> Result { + let extended_id = embedded_can::ExtendedId::new(raw_id).ok_or(IdCreateError::OutOfRange)?; + Ok(Id { 0: extended_id.into() }) + } +} + +impl From for embedded_can::Id { + fn from(id: Id) -> Self { + id.0 + } +} + #[cfg(feature = "defmt")] impl defmt::Format for Header { fn format(&self, fmt: defmt::Formatter<'_>) { @@ -39,19 +70,27 @@ impl Header { const FLAG_BRS: usize = 2; // Bit-rate switching, ignored for Classic CAN /// Create new CAN Header - pub fn new(id: embedded_can::Id, len: u8, rtr: bool) -> Header { + pub fn new(id: impl Into, len: u8, rtr: bool) -> Header { let mut flags = 0u8; flags.set_bit(Self::FLAG_RTR, rtr); - Header { id, len, flags } + Header { + id: id.into(), + len, + flags, + } } /// Create new CAN FD Header - pub fn new_fd(id: embedded_can::Id, len: u8, rtr: bool, brs: bool) -> Header { + pub fn new_fd(id: impl Into, len: u8, rtr: bool, brs: bool) -> Header { let mut flags = 0u8; flags.set_bit(Self::FLAG_RTR, rtr); flags.set_bit(Self::FLAG_FDCAN, true); flags.set_bit(Self::FLAG_BRS, brs); - Header { id, len, flags } + Header { + id: id.into(), + len, + flags, + } } /// Return ID @@ -170,7 +209,7 @@ impl Frame { /// Create new extended frame pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result { if let Some(id) = embedded_can::ExtendedId::new(raw_id) { - Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data) + Self::new(Header::new(id, raw_data.len() as u8, false), raw_data) } else { Err(FrameCreateError::InvalidCanId) } @@ -179,7 +218,7 @@ impl Frame { /// Create new standard frame pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result { if let Some(id) = embedded_can::StandardId::new(raw_id) { - Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data) + Self::new(Header::new(id, raw_data.len() as u8, false), raw_data) } else { Err(FrameCreateError::InvalidCanId) } @@ -352,9 +391,10 @@ impl FdFrame { } /// Create new extended frame + /// BRS is set to false by default pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result { if let Some(id) = embedded_can::ExtendedId::new(raw_id) { - Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data) + Self::new(Header::new(id, raw_data.len() as u8, false), raw_data) } else { Err(FrameCreateError::InvalidCanId) } @@ -363,7 +403,7 @@ impl FdFrame { /// Create new standard frame pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result { if let Some(id) = embedded_can::StandardId::new(raw_id) { - Self::new(Header::new(id.into(), raw_data.len() as u8, false), raw_data) + Self::new(Header::new(id, raw_data.len() as u8, false), raw_data) } else { Err(FrameCreateError::InvalidCanId) }