Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
dstric-aqueduct committed Nov 17, 2022
1 parent dc9581c commit 6362ad6
Show file tree
Hide file tree
Showing 10 changed files with 2,017 additions and 0 deletions.
107 changes: 107 additions & 0 deletions imxrt1060-hal/src/can/embedded_hal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//! `embedded_hal` trait impls.
use super::{Data, ExtendedId, Frame, Id, IdReg, OverrunError, StandardId, CAN};

use crate::iomuxc::consts::Unsigned;
use embedded_hal::can;

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

type Error = OverrunError;

fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
let data: [u8; 8] = [255, 255, 255, 255, 255, 255, 255, 255];
let id = StandardId::new(0).unwrap();

match self.transmit(frame) {
Ok(status) => Ok(Some(Frame::new_data(id, Data::new(&data).unwrap()))),
Err(nb::Error::WouldBlock) => Err(nb::Error::WouldBlock),
Err(nb::Error::Other(e)) => match e {},
}
}

fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
let data: [u8; 8] = [255, 255, 255, 255, 255, 255, 255, 255];
let id = StandardId::new(0).unwrap();

Ok(Frame::new_data(id, Data::new(&data).unwrap()))
}
}

impl can::Error for OverrunError {
fn kind(&self) -> can::ErrorKind {
can::ErrorKind::Overrun
}
}

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 {
&[]
}
}
}
213 changes: 213 additions & 0 deletions imxrt1060-hal/src/can/filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
//! Filter bank API.
use core::marker::PhantomData;

use super::{ExtendedId, Fifo, Id, StandardId};

const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames
const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers
const F16_RTR: u16 = 0b10000;
const F16_IDE: u16 = 0b01000;

/// A 16-bit filter list entry.
///
/// This can match data and remote frames using standard IDs.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct ListEntry16(u16);

/// A 32-bit filter list entry.
///
/// This can match data and remote frames using extended or standard IDs.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct ListEntry32(u32);

/// A 16-bit identifier mask.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct Mask16 {
id: u16,
mask: u16,
}

/// A 32-bit identifier mask.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct Mask32 {
id: u32,
mask: u32,
}

impl ListEntry16 {
/// Creates a filter list entry that accepts data frames with the given standard ID.
///
/// This entry will *not* accept remote frames with the same ID.
pub fn data_frames_with_id(id: StandardId) -> Self {
Self(id.as_raw() << 5)
}

/// Creates a filter list entry that accepts remote frames with the given standard ID.
pub fn remote_frames_with_id(id: StandardId) -> Self {
Self(id.as_raw() << 5 | F16_RTR)
}
}

impl ListEntry32 {
/// Creates a filter list entry that accepts data frames with the given ID.
///
/// This entry will *not* accept remote frames with the same ID.
///
/// The filter will only accept *either* standard *or* extended frames, depending on `id`.
pub fn data_frames_with_id(id: impl Into<Id>) -> Self {
match id.into() {
Id::Standard(id) => Self(u32::from(id.as_raw()) << 21),
Id::Extended(id) => Self(id.as_raw() << 3 | F32_IDE),
}
}

/// Creates a filter list entry that accepts remote frames with the given ID.
pub fn remote_frames_with_id(id: impl Into<Id>) -> Self {
match id.into() {
Id::Standard(id) => Self(u32::from(id.as_raw()) << 21 | F32_RTR),
Id::Extended(id) => Self(id.as_raw() << 3 | F32_IDE | F32_RTR),
}
}
}

impl Mask16 {
/// Creates a 16-bit identifier mask that accepts all frames.
///
/// This will accept both standard and extended data and remote frames with any ID.
pub fn accept_all() -> Self {
Self { id: 0, mask: 0 }
}

/// Creates a 16-bit identifier mask that accepts all frames with the given standard
/// ID and mask combination.
///
/// Filter logic: `frame_accepted = (incoming_id & mask) == (id & mask)`
///
/// A mask of all all ones (`0x7FF`) matches an exact ID, a mask of 0 matches all IDs.
///
/// Both data and remote frames with `id` will be accepted. Any extended frames will be
/// rejected.
pub fn frames_with_std_id(id: StandardId, mask: StandardId) -> Self {
Self {
id: id.as_raw() << 5,
mask: mask.as_raw() << 5 | F16_IDE, // also require IDE = 0
}
}

/// Make the filter accept data frames only.
pub fn data_frames_only(&mut self) -> &mut Self {
self.id &= !F16_RTR; // RTR = 0
self.mask |= F16_RTR;
self
}

/// Make the filter accept remote frames only.
pub fn remote_frames_only(&mut self) -> &mut Self {
self.id |= F16_RTR; // RTR = 1
self.mask |= F16_RTR;
self
}
}

impl Mask32 {
/// Creates a 32-bit identifier mask that accepts all frames.
///
/// This will accept both standard and extended data and remote frames with any ID.
pub fn accept_all() -> Self {
Self { id: 0, mask: 0 }
}

/// Creates a 32-bit identifier mask that accepts all frames with the given extended
/// ID and mask combination.
///
/// Filter logic: `frame_accepted = (incoming_id & mask) == (id & mask)`
///
/// A mask of all all ones (`0x1FFF_FFFF`) matches an exact ID, a mask of 0 matches all IDs.
///
/// Both data and remote frames with `id` will be accepted. Standard frames will be rejected.
pub fn frames_with_ext_id(id: ExtendedId, mask: ExtendedId) -> Self {
Self {
id: id.as_raw() << 3 | F32_IDE,
mask: mask.as_raw() << 3 | F32_IDE, // also require IDE = 1
}
}

/// Creates a 32-bit identifier mask that accepts all frames with the given standard
/// ID and mask combination.
///
/// Filter logic: `frame_accepted = (incoming_id & mask) == (id & mask)`
///
/// A mask of all all ones (`0x7FF`) matches the exact ID, a mask of 0 matches all IDs.
///
/// Both data and remote frames with `id` will be accepted. Extended frames will be rejected.
pub fn frames_with_std_id(id: StandardId, mask: StandardId) -> Self {
Self {
id: u32::from(id.as_raw()) << 21,
mask: u32::from(mask.as_raw()) << 21 | F32_IDE, // also require IDE = 0
}
}

/// Make the filter accept data frames only.
pub fn data_frames_only(&mut self) -> &mut Self {
self.id &= !F32_RTR; // RTR = 0
self.mask |= F32_RTR;
self
}

/// Make the filter accept remote frames only.
pub fn remote_frames_only(&mut self) -> &mut Self {
self.id |= F32_RTR; // RTR = 1
self.mask |= F32_RTR;
self
}
}

/// The configuration of a filter bank.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub enum BankConfig {
List16([ListEntry16; 4]),
List32([ListEntry32; 2]),
Mask16([Mask16; 2]),
Mask32(Mask32),
}

impl From<[ListEntry16; 4]> for BankConfig {
#[inline]
fn from(entries: [ListEntry16; 4]) -> Self {
Self::List16(entries)
}
}

impl From<[ListEntry32; 2]> for BankConfig {
#[inline]
fn from(entries: [ListEntry32; 2]) -> Self {
Self::List32(entries)
}
}

impl From<[Mask16; 2]> for BankConfig {
#[inline]
fn from(entries: [Mask16; 2]) -> Self {
Self::Mask16(entries)
}
}

impl From<Mask32> for BankConfig {
#[inline]
fn from(filter: Mask32) -> Self {
Self::Mask32(filter)
}
}

#[cfg(test)]
mod tests {
use super::*;


}
Loading

0 comments on commit 6362ad6

Please sign in to comment.