Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CAN Interface #3555

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions embassy-stm32/src/can/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
58 changes: 49 additions & 9 deletions embassy-stm32/src/can/frame.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand All @@ -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<u16> for Id {
type Error = IdCreateError;

fn try_from(raw_id: u16) -> Result<Self, Self::Error> {
let standard_id = embedded_can::StandardId::new(raw_id).ok_or(IdCreateError::OutOfRange)?;
Ok(Id { 0: standard_id.into() })
}
}

impl TryFrom<u32> for Id {
type Error = IdCreateError;

fn try_from(raw_id: u32) -> Result<Self, Self::Error> {
let extended_id = embedded_can::ExtendedId::new(raw_id).ok_or(IdCreateError::OutOfRange)?;
Ok(Id { 0: extended_id.into() })
}
}

impl From<Id> 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<'_>) {
Expand All @@ -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<embedded_can::Id>, 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<embedded_can::Id>, 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
Expand Down Expand Up @@ -170,7 +209,7 @@ impl Frame {
/// Create new extended frame
pub fn new_extended(raw_id: u32, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
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)
}
Expand All @@ -179,7 +218,7 @@ impl Frame {
/// Create new standard frame
pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
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)
}
Expand Down Expand Up @@ -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<Self, FrameCreateError> {
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)
}
Expand All @@ -363,7 +403,7 @@ impl FdFrame {
/// Create new standard frame
pub fn new_standard(raw_id: u16, raw_data: &[u8]) -> Result<Self, FrameCreateError> {
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)
}
Expand Down