Skip to content

Commit

Permalink
embedded-can-04: Add a receive function for an arbitrary embedded_can…
Browse files Browse the repository at this point in the history
…::Frame.

Classic CAN only, as no CAN-FD support in embedded_can yet.
  • Loading branch information
projectgus committed Oct 17, 2024
1 parent 1157869 commit 594b742
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## [Unreleased]

* Update MSRV to 1.60
* Add `embedded-can-04` feature flag which enables conversions from and into `embedded_can::Id` types, and compatible transmit functions.
* Add `embedded-can-04` feature flag which enables conversions from and into `embedded_can::Id` types, and compatible receive and transmit functions.

## [v0.2.1] 2024-09-04

Expand Down
63 changes: 59 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//!
//! | Feature | Description |
//! |---------|-------------|
//! | `embedded-can-04` | Enables conversions from and into [`embedded_can`] 0.4 CAN ID types, and compatible transmit functions. |
//! | `embedded-can-04` | Enables conversions from and into [`embedded_can`] 0.4 CAN ID types, and compatible receive transmit functions. Note that only classic CAN is currently supported in `embedded_can`. |
//!
//! [`embedded-can`]: https://docs.rs/embedded-can
Expand Down Expand Up @@ -52,7 +52,7 @@ use filter::{
StandardFilterSlot, EXTENDED_FILTER_MAX, STANDARD_FILTER_MAX,
};
use frame::MergeTxFrameHeader;
use frame::{RxFrameInfo, TxFrameHeader};
use frame::{FrameFormat, RxFrameInfo, TxFrameHeader};
use id::{Id, IdReg};
use interrupt::{Interrupt, InterruptLine, Interrupts};

Expand Down Expand Up @@ -1140,6 +1140,36 @@ where
// Safety: We have a `&mut self` and have unique access to the peripheral.
unsafe { Rx::<I, M, Fifo1>::conjure().receive(buffer) }
}

/// Returns a received Classic CAN frame of a given type from FIFO_0 if available.
///
/// # Panics
///
/// Panics if an `CAN-FD` frame is received, as embedded_can::Frame has no FD support.
#[cfg(feature = "embedded-can-04")]
#[inline]
pub fn receive0_frame<F>(&mut self) -> nb::Result<ReceiveOverrun<F>, Infallible>
where
F: embedded_can::Frame,
{
// Safety: We have a `&mut self` and have unique access to the peripheral.
unsafe { Rx::<I, M, Fifo0>::conjure().receive_frame() }
}

/// Returns a received Classic CAN frame of a given type from FIFO_1 if available.
///
/// # Panics
///
/// Panics if an `CAN-FD` frame is received, as embedded_can::Frame has no FD support.
#[cfg(feature = "embedded-can-04")]
#[inline]
pub fn receive1_frame<F>(&mut self) -> nb::Result<ReceiveOverrun<F>, Infallible>
where
F: embedded_can::Frame,
{
// Safety: We have a `&mut self` and have unique access to the peripheral.
unsafe { Rx::<I, M, Fifo1>::conjure().receive_frame() }
}
}

/// FdCanControl Struct
Expand Down Expand Up @@ -1567,8 +1597,6 @@ where

/// Returns a received frame if available.
///
/// Returns `Err` when a frame was lost due to buffer overrun.
///
/// # Panics
///
/// Panics if `buffer` is smaller than the header length.
Expand Down Expand Up @@ -1607,6 +1635,33 @@ where
}
}

/// Returns a received Classic CAN frame of a given type if available.
///
/// # Panics
///
/// Panics if an `CAN-FD` frame is received, as embedded_can::Frame has no FD support.
#[cfg(feature = "embedded-can-04")]
pub fn receive_frame<F>(mut self) -> nb::Result<ReceiveOverrun<F>, Infallible>
where
F: embedded_can::Frame,
{
let mut buffer = [0_u8; 8];
let overrun = self.receive(&mut buffer)?;
let info = overrun.unwrap();
if info.frame_format != FrameFormat::Standard {
panic!("Received CAN-FD frame");
}
let frame = if info.rtr {
F::new_remote(info.id, info.len as usize)
} else {
F::new(info.id, &buffer[..info.len as usize])
}.unwrap();
match overrun {
ReceiveOverrun::NoOverrun(_) => Ok(ReceiveOverrun::NoOverrun(frame)),
ReceiveOverrun::Overrun(_) => Ok(ReceiveOverrun::Overrun(frame)),
}
}

#[inline]
fn registers(&self) -> &RegisterBlock {
unsafe { &*I::REGISTERS }
Expand Down

0 comments on commit 594b742

Please sign in to comment.