Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target
.idea
.vscode
Cargo.lock
6 changes: 3 additions & 3 deletions imxrt-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ log = "0.4.8"
rand_core = { version = "0.5", default-features = false, optional = true }

[dependencies.imxrt-iomuxc]
version = "0.1.2"
git = "https://github.com/imxrt-rs/imxrt-iomuxc.git"
branch = "v0.1"
features = ["imxrt106x"]
git = "https://github.com/dstric-aqueduct/imxrt-iomuxc.git"
tag = "v0.1.5-can"

[dev-dependencies.cortex-m-rt]
version = "0.6"
Expand Down
110 changes: 110 additions & 0 deletions imxrt-hal/src/can/embedded_hal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//! `embedded_hal` trait impls.

use super::{Data, Error, Frame, CAN};
use crate::iomuxc::consts::Unsigned;

use embedded_hal::can;
pub(crate) use embedded_hal::can::ErrorKind;
pub use embedded_hal::can::{ExtendedId, Id, StandardId};

impl<M> can::Can for CAN<M>
where
M: Unsigned,
{
type Frame = Frame;

type Error = Error;

fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
match self.transmit(frame) {
Ok(_status) => Ok(Some(frame.clone())),
Err(nb::Error::WouldBlock) => Err(nb::Error::WouldBlock),
Err(nb::Error::Other(e)) => Err(nb::Error::Other(e)),
}
}

fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
match self.read_mailboxes() {
Some(d) => Ok(d.frame),
None => Err(nb::Error::Other(Error::NoRxData)),
}
}
}

impl can::Error for Error {
fn kind(&self) -> can::ErrorKind {
match self {
Self::NoRxData => can::ErrorKind::Other,
Self::NoTxMailbox => can::ErrorKind::Other,
Self::EmbeddedHal(e) => e.kind(),
}
}
}

impl can::Frame for Frame {
fn new(id: impl Into<can::Id>, data: &[u8]) -> Option<Self> {
let id = match id.into() {
can::Id::Standard(id) => unsafe {
Id::Standard(StandardId::new_unchecked(id.as_raw()))
},
can::Id::Extended(id) => unsafe {
Id::Extended(ExtendedId::new_unchecked(id.as_raw()))
},
};

let data = Data::new(data)?;
Some(Frame::new_data(id, data))
}

fn new_remote(id: impl Into<can::Id>, dlc: usize) -> Option<Self> {
let id = match id.into() {
can::Id::Standard(id) => unsafe {
Id::Standard(StandardId::new_unchecked(id.as_raw()))
},
can::Id::Extended(id) => unsafe {
Id::Extended(ExtendedId::new_unchecked(id.as_raw()))
},
};

if dlc <= 8 {
Some(Frame::new_remote(id, dlc as u8))
} else {
None
}
}

#[inline]
fn is_extended(&self) -> bool {
self.is_extended()
}

#[inline]
fn is_remote_frame(&self) -> bool {
self.is_remote_frame()
}

#[inline]
fn id(&self) -> can::Id {
match self.id() {
Id::Standard(id) => unsafe {
can::Id::Standard(can::StandardId::new_unchecked(id.as_raw()))
},
Id::Extended(id) => unsafe {
can::Id::Extended(can::ExtendedId::new_unchecked(id.as_raw()))
},
}
}

#[inline]
fn dlc(&self) -> usize {
self.dlc().into()
}

fn data(&self) -> &[u8] {
if let Some(data) = self.data() {
data
} else {
&[]
}
}
}
38 changes: 38 additions & 0 deletions imxrt-hal/src/can/filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! Filter bank API.

#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum FlexCanIde {
#[default]
None = 0,
Ext = 1,
Rtr = 2,
Std = 3,
Inactive,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum FlexCanFlten {
AcceptAll = 0,
#[default]
RejectAll = 1,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub struct FlexCanFilter {
pub filter_id: u8,
pub id: u32,
pub ide: FlexCanIde,
pub remote: FlexCanIde,
}

impl FlexCanFilter {
/// Create a new [`FlexCanFilter`].
pub fn new(filter_id: u8, id: u32, ide: FlexCanIde, remote: FlexCanIde) -> Self {
Self {
filter_id,
id,
ide,
remote,
}
}
}
Loading