Skip to content
Draft
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
a0fcb3b
Prototype a FlexCAN peripheral
dstric-aqueduct Dec 18, 2022
e7c6bef
Remove StandardId and ExtendedId structs in favor of embedded-hal
dstric-aqueduct Dec 18, 2022
567623f
use get_clock() instead of hard code freq for baud rate calc
dstric-aqueduct Dec 18, 2022
001e975
PR updates
dstric-aqueduct Dec 21, 2022
7072a37
remove unused import, added derives to FlexCanMailboxCSCode
dstric-aqueduct Dec 24, 2022
d37b511
fix to mod.rs docs
dstric-aqueduct Dec 26, 2022
0696fe1
PR updates
dstric-aqueduct Dec 28, 2022
0e67341
Prototype a FlexCAN peripheral
dstric-aqueduct Dec 18, 2022
14aabd7
fix clippy warnings
dstric-aqueduct Jan 1, 2023
2bda636
Fix formatting
mciantyre Jan 1, 2023
e75e127
Run 'cargo clippy --fix' to resolve some warnings
mciantyre Jan 1, 2023
f4f8bf3
Simplify conditional expressions with u32::from
mciantyre Jan 1, 2023
0a52f37
update to address overflow in baud rate calc
dstric-aqueduct Jan 11, 2023
d9719aa
add flexcan_clk clock root to ccm
sigil-03 Aug 13, 2024
bb4cb3b
pushing local changes
sigil-03 Aug 14, 2024
0aeaa05
fix comments referencing LP12C instead of flexcan
sigil-03 Aug 14, 2024
69e83be
add flexcan and flexcan_pe clock gate locators
sigil-03 Aug 14, 2024
75222f7
add remainder of clock selections for flexcan_clk
sigil-03 Aug 14, 2024
603f406
update naming of PLLs and clock root to match crate and user manual
sigil-03 Aug 14, 2024
e5fb282
add flexcan clock gates
sigil-03 Aug 14, 2024
c27a696
update names
sigil-03 Aug 14, 2024
900262d
comment out unused things to allow compile, fix type templates
sigil-03 Aug 14, 2024
5dd2488
update clock tree information
sigil-03 Aug 14, 2024
ca785ef
comment out unused CAN builder
sigil-03 Aug 14, 2024
95ffd35
fix clock frequency
sigil-03 Aug 14, 2024
b360ab3
fix OOB read bug in read_mailbox
sigil-03 Aug 14, 2024
39d0a9f
clean up mod.rs
sigil-03 Aug 14, 2024
72a74fa
remove unused can clocking definition file
sigil-03 Aug 15, 2024
d7f8975
change CAN to be a chip-specific driver
sigil-03 Aug 19, 2024
9c8957a
fix whitespace formatting
sigil-03 Aug 19, 2024
1d054b6
change clock control file locations
sigil-03 Aug 19, 2024
f83953d
fix whitespace issue
sigil-03 Aug 19, 2024
b19ad1e
fix formatting
sigil-03 Aug 19, 2024
bcc75a1
fix module scoping for CAN clock gates
sigil-03 Aug 19, 2024
8f64296
fix mod scoping a g a i n
sigil-03 Aug 19, 2024
4e089d9
fix where clock gate locators are pointed
sigil-03 Aug 19, 2024
129454a
add #[allow(unused)] to fix empty driver issue
sigil-03 Aug 20, 2024
2e2536d
make fixes to scoping of can clock gates/tree
sigil-03 Aug 20, 2024
ddee7ba
remove unused variables + switch pins to phantomdata
sigil-03 Aug 20, 2024
ee48bd4
add doc strings to can module
sigil-03 Aug 20, 2024
11a129c
add filter doc strings
sigil-03 Aug 20, 2024
91d5e38
add docstrings to frame.rs
sigil-03 Aug 20, 2024
c2b0b52
fix docstrings in chip defs
sigil-03 Aug 20, 2024
3664cff
fix indentation
sigil-03 Aug 20, 2024
ea66169
fix doc code example
sigil-03 Aug 20, 2024
027f291
fix docstring references
sigil-03 Aug 20, 2024
d5e4b4f
fix docstring references to private items
sigil-03 Aug 20, 2024
6a37344
Make FlexCAN drivers chip-specific + fix docs
sigil-03 Aug 20, 2024
1a0f321
fix CAN frame decoding
sigil-03 Oct 16, 2024
132a670
Merge pull request #3 from sigil-03/fix/can-frame-decoding
sigil-03 Oct 16, 2024
dbe45d4
Add DLC fix and frame parsing from slice
sigil-03 Oct 29, 2024
5a1ba4b
Merge pull request #5 from sigil-03/dlc-length-fix
sigil-03 Oct 29, 2024
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
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ version = "0.2.6"
package = "embedded-hal"
version = "1.0.0"

[dependencies.embedded_can]
package = "embedded-can"
version = "0.4.1"

[dependencies.eio06]
package = "embedded-io"
version = "0.6.1"
Expand Down
20 changes: 20 additions & 0 deletions board/src/imxrt10xx/clock_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,26 @@ pub const fn lpi2c_frequency(run_mode: RunMode) -> u32 {

const _: () = assert!(lpi2c_frequency(RunMode::Overdrive) == 8_000_000); // Max is 66MHz.

// const fn can_divider(run_mode: RunMode) -> u32 {
// match run_mode {
// RunMode::Overdrive => 1,
// }
// }

// const fn can_selection(run_mode: RunMode) -> lpi2c_clk::Selection {
// match run_mode {
// RunMode::Overdrive => can_clk::Selection::Oscillator,
// }
// }

// /// Returns the CAN clock frequency for the run mode
// pub const fn can_frequency(run_mode: RunMode) -> u32 {
// let hz = match run_mode {
// RunMode::Overdrive => XTAL_OSCILLATOR_HZ,
// };
// hz / can_divider(run_mode)
// }

/// Configure the PERCLK root clock.
///
/// When this call returns, the PERCLK clock frequency match the values
Expand Down
5 changes: 5 additions & 0 deletions src/chip/imxrt10xx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ pub(crate) mod reexports {
pub use super::{adc, dcdc, tempmon, trng};
}

pub(crate) mod drivers {
#[allow(unused)] // Not entirely sure how to work around this. Could use some help here!
pub use super::config::drivers::*;
}

pub(crate) mod iomuxc {
pub use super::config::pads;
use crate::ral;
Expand Down
11 changes: 11 additions & 0 deletions src/chip/imxrt10xx/ccm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ use crate::ral;

pub use crate::common::ccm::XTAL_OSCILLATOR_HZ;

// pub struct Handle {
// pub(crate) base: ral::ccm::Instance,
// pub(crate) analog: ral::ccm_analog::Instance,
// }
//
// impl Handle {
// pub fn raw(&mut self) -> (&ral::ccm::Instance, &ral::ccm_analog::Instance) {
// (&self.base, &self.analog)
// }
// }

/// PERCLK clock.
///
/// The PERCLK clock controls GPT and PIT timers.
Expand Down
52 changes: 52 additions & 0 deletions src/chip/imxrt10xx/ccm/can_clk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/// CAN clock root
use crate::ral::{self, ccm::CCM};

/// Returns the can clock divider.
#[inline(always)]
pub fn divider(ccm: &CCM) -> u32 {
ral::read_reg!(ral::ccm, ccm, CSCMR2, CAN_CLK_PODF) + 1
}

/// The smallest flexcan clock divider.
pub const MIN_DIVIDER: u32 = 1;
/// The largest flexcan clock divider.
pub const MAX_DIVIDER: u32 = 64;

/// Set the flexcan clock divider
#[inline(always)]
pub fn set_divider(ccm: &mut CCM, divider: u32) {
let podf = divider.clamp(MIN_DIVIDER, MAX_DIVIDER) - 1;
ral::modify_reg!(ral::ccm, ccm, CSCMR2, CAN_CLK_PODF: podf);
}

/// Flexcan clock selections.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Selection {
/// Derive from pll3_sw_clk divided clock (60M)
PLL3Div8 = 0,
/// Derive from the crystal oscillator.
Oscillator = 1,
/// Derive from pll3_sw_clk divided clock (80M)
PLL3Div6 = 2,
/// Disable flexcan clock
Disable = 3,
Comment on lines +32 to +33
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for other / future reviewers: This variant is not documented in the 1020 reference manual. It's also not a constant known to the 1020 SVD. Nevertheless, I say we keep this as-is; we cover the full bit width of the field.

}

/// Returns the Flexcan clock selection.
#[inline(always)]
pub fn selection(ccm: &CCM) -> Selection {
match ral::read_reg!(ral::ccm, ccm, CSCMR2, CAN_CLK_SEL) {
0 => Selection::PLL3Div8,
1 => Selection::Oscillator,
2 => Selection::PLL3Div6,
3 => Selection::Disable,
_ => unreachable!(),
}
}

/// Set the Flexcan clock selection.
#[inline(always)]
pub fn set_selection(ccm: &mut CCM, selection: Selection) {
ral::modify_reg!(ral::ccm, ccm, CSCMR2, CAN_CLK_SEL: selection as u32);
}
6 changes: 3 additions & 3 deletions src/chip/imxrt10xx/ccm/clock_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl Setting {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(unused)]
#[repr(u8)]
enum Register {
pub(crate) enum Register {
CCGR0,
CCGR1,
CCGR2,
Expand All @@ -107,7 +107,7 @@ use Register::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(unused)]
#[repr(u8)]
enum Gate {
pub(crate) enum Gate {
CG0,
CG1,
CG2,
Expand Down Expand Up @@ -147,7 +147,7 @@ pub struct Locator {
gate: Gate,
}

const fn locator(register: Register, gate: Gate) -> Locator {
pub(crate) const fn locator(register: Register, gate: Gate) -> Locator {
Locator { register, gate }
}

Expand Down
27 changes: 27 additions & 0 deletions src/chip/imxrt10xx/ccm/clock_gate/can.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::ccm::clock_gate::{locator, Gate::*, Locator, Register::*};
use crate::ral;
/// Returns the FlexCAN clock gate locator.
#[inline(always)]
pub const fn can<const N: u8>() -> Locator
where
ral::can::Instance<N>: ral::Valid,
{
[locator(CCGR0, CG7), locator(CCGR0, CG9)][if N == ral::SOLE_INSTANCE {
N as usize
} else {
N as usize - 1
}]
}

/// Returns the FlexCAN Peripheral Engine gate locator.
#[inline(always)]
pub const fn can_pe<const N: u8>() -> Locator
where
ral::can::Instance<N>: ral::Valid,
{
[locator(CCGR0, CG8), locator(CCGR0, CG10)][if N == ral::SOLE_INSTANCE {
N as usize
} else {
N as usize - 1
}]
}
94 changes: 94 additions & 0 deletions src/chip/imxrt10xx/drivers/can/embedded_hal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! `embedded_hal` trait impls.

use super::{Data, Error, Frame, CAN};

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

impl<P, const M: u8> embedded_can::nb::Can for CAN<P, M> {
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 embedded_can::Error for Error {
fn kind(&self) -> embedded_can::ErrorKind {
match self {
Self::NoRxData => embedded_can::ErrorKind::Other,
Self::NoTxMailbox => embedded_can::ErrorKind::Other,
Self::EmbeddedHal(e) => e.kind(),
}
}
}

impl embedded_can::Frame for Frame {
fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
let id = match id.into() {
Id::Standard(id) => unsafe { Id::Standard(StandardId::new_unchecked(id.as_raw())) },
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<Id>, dlc: usize) -> Option<Self> {
let id = match id.into() {
Id::Standard(id) => unsafe { Id::Standard(StandardId::new_unchecked(id.as_raw())) },
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) -> Id {
match self.id() {
Id::Standard(id) => unsafe { Id::Standard(StandardId::new_unchecked(id.as_raw())) },
Id::Extended(id) => unsafe { Id::Extended(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 {
&[]
}
}
}
54 changes: 54 additions & 0 deletions src/chip/imxrt10xx/drivers/can/filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Filter bank API.

/// Decodes value of the ID Extended (IDE) and Remote Transmission Request (RTR) bits
///
/// TODO: Break this up into seperate RTR and IDE structs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the plan to address these TODOs? I see the options as

  1. Now, during this review.
  2. After we merge, but before we release.
  3. After we release, in a breaking change.

Question and options applies to other TODOs listed in documentation. I'd prefer option 1, or option 2 if it can happen soon after we merge.

(In this instance, I haven't thought if separation is appropriate. I'll change my consideration if the answer is option 1.)

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

/// Filter enable/disable.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum FlexCanFlten {
/// Accept all CAN frames (filtering is disabled)
AcceptAll = 0,
/// Reject all CAN frames that do not match the filter exactly
#[default]
RejectAll = 1,
}

/// FlexCAN Filter.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub struct FlexCanFilter {
/// Mailbox ID that this filter will apply to
pub filter_id: u8,
/// Frame ID
pub id: u32,
/// Extended ID Bit (IDE)
pub ide: FlexCanIde,
/// Remote Frame Bit (RTR)
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