Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dstric-aqueduct committed Nov 21, 2022
1 parent 6362ad6 commit 10a66d2
Show file tree
Hide file tree
Showing 6 changed files with 606 additions and 169 deletions.
6 changes: 2 additions & 4 deletions imxrt1060-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ git = "https://github.com/imxrt-rs/imxrt-ral"
features = ["imxrt1062"]

[dependencies.imxrt-iomuxc]
version = "0.2.0"
git = "https://github.com/imxrt-rs/imxrt-iomuxc.git"
rev = "dffa37438b362ad598015db90f8b2d4b6c71b609"
features = ["imxrt1060"]
version = "0.1.5"
features = ["imxrt106x"]

[dev-dependencies.cortex-m-rt]
version = "0.6"
Expand Down
2 changes: 1 addition & 1 deletion imxrt1060-hal/src/can/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod tests;
use core::cmp::Ordering;
use core::ops::{Deref, DerefMut};

use super::{Id, IdReg};
use super::id::{Id, IdReg};

/// A CAN data or remote frame.
#[derive(Clone, Debug, Eq)]
Expand Down
4 changes: 1 addition & 3 deletions imxrt1060-hal/src/can/frame/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use super::Frame;
use super::id::{ExtendedId, Id, StandardId};

use crate::can::{frame::Frame, id::{ExtendedId, StandardId}};

#[test]
fn data_greater_remote() {
Expand Down
124 changes: 123 additions & 1 deletion imxrt1060-hal/src/can/id.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,126 @@
//! CAN Identifiers.
use crate::ccm;
use crate::iomuxc::consts::{Unsigned, U1, U2};
use crate::ral;

use core::cmp::{Ord, Ordering};
use core::marker::PhantomData;
use core::ptr::NonNull;

/// Identifier of a CAN message.
///
/// Can be either a standard identifier (11bit, Range: 0..0x3FF) or a
/// extendended identifier (29bit , Range: 0..0x1FFFFFFF).
///
/// The `Ord` trait can be used to determine the frame’s priority this ID
/// belongs to.
/// Lower identifier values have a higher priority. Additionally standard frames
/// have a higher priority than extended frames and data frames have a higher
/// priority than remote frames.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct IdReg(u32);

impl IdReg {
const STANDARD_SHIFT: u32 = 21;

const EXTENDED_SHIFT: u32 = 3;

const IDE_MASK: u32 = 0x0000_0004;

const RTR_MASK: u32 = 0x0000_0002;

/// Creates a new standard identifier (11bit, Range: 0..0x7FF)
///
/// Panics for IDs outside the allowed range.
pub fn new_standard(id: StandardId) -> Self {
Self(u32::from(id.as_raw()) << Self::STANDARD_SHIFT)
}

/// Creates a new extendended identifier (29bit , Range: 0..0x1FFFFFFF).
///
/// Panics for IDs outside the allowed range.
pub fn new_extended(id: ExtendedId) -> IdReg {
Self(id.as_raw() << Self::EXTENDED_SHIFT | Self::IDE_MASK)
}

fn from_register(reg: u32) -> IdReg {
Self(reg & 0xFFFF_FFFE)
}

/// Sets the remote transmission (RTR) flag. This marks the identifier as
/// being part of a remote frame.
#[must_use = "returns a new IdReg without modifying `self`"]
pub fn with_rtr(self, rtr: bool) -> IdReg {
if rtr {
Self(self.0 | Self::RTR_MASK)
} else {
Self(self.0 & !Self::RTR_MASK)
}
}

/// Returns the identifier.
pub fn to_id(self) -> Id {
if self.is_extended() {
Id::Extended(unsafe { ExtendedId::new_unchecked(self.0 >> Self::EXTENDED_SHIFT) })
} else {
Id::Standard(unsafe {
StandardId::new_unchecked((self.0 >> Self::STANDARD_SHIFT) as u16)
})
}
}

/// Returns `true` if the identifier is an extended identifier.
pub fn is_extended(self) -> bool {
self.0 & Self::IDE_MASK != 0
}

/// Returns `true` if the identifier is a standard identifier.
pub fn is_standard(self) -> bool {
!self.is_extended()
}

/// Returns `true` if the identifer is part of a remote frame (RTR bit set).
pub fn rtr(self) -> bool {
self.0 & Self::RTR_MASK != 0
}
}

/// `IdReg` is ordered by priority.
impl Ord for IdReg {
fn cmp(&self, other: &Self) -> Ordering {
// When the IDs match, data frames have priority over remote frames.
let rtr = self.rtr().cmp(&other.rtr()).reverse();

let id_a = self.to_id();
let id_b = other.to_id();
match (id_a, id_b) {
(Id::Standard(a), Id::Standard(b)) => {
// Lower IDs have priority over higher IDs.
a.as_raw().cmp(&b.as_raw()).reverse().then(rtr)
}
(Id::Extended(a), Id::Extended(b)) => a.as_raw().cmp(&b.as_raw()).reverse().then(rtr),
(Id::Standard(a), Id::Extended(b)) => {
// Standard frames have priority over extended frames if their Base IDs match.
a.as_raw()
.cmp(&b.standard_id().as_raw())
.reverse()
.then(Ordering::Greater)
}
(Id::Extended(a), Id::Standard(b)) => a
.standard_id()
.as_raw()
.cmp(&b.as_raw())
.reverse()
.then(Ordering::Less),
}
}
}

impl PartialOrd for IdReg {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

/// Standard 11-bit CAN Identifier (`0..=0x7FF`).
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
Expand Down
Loading

0 comments on commit 10a66d2

Please sign in to comment.