Skip to content

Commit

Permalink
resolve PR Issues
Browse files Browse the repository at this point in the history
- remove artifacts of non-existent feature: imxrt-rs#122 (comment)

- remove constrain function and use core::cmp::Ordering::clamp trait: imxrt-rs#122 (comment)

- fix to add Can to ccm mod

- remove const def of base registers

- fix to hard code Can clock source to OSC

see: imxrt-rs#122 (comment)

- update to add new iomuxc crate
  • Loading branch information
dstric-aqueduct committed Dec 14, 2022
1 parent 081d027 commit bff2cae
Show file tree
Hide file tree
Showing 18 changed files with 955 additions and 441 deletions.
41 changes: 32 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Thanks for helping us build embedded Rust support for NXP's i.MX RT processors! Please open an issue if

- you find a bug in any chip HAL
- you find a bug in the HAL, RAL, or IOMUXC crates
- you have an idea for a feature
- something isn't clear in our documentation

Expand All @@ -20,22 +20,45 @@ You'll need
```bash
rustup target add thumbv7em-none-eabihf
```
### Chip-specific HAL(s)

We support one HAL crate per i.MX RT processor family. A "processor family" is described by an NXP datasheet and reference manual. For example, the `imxrt1060-hal` supports the [i.MX RT1060 Crossover Processors](https://www.nxp.com/docs/en/nxp/data-sheets/IMXRT1060CEC.pdf), which includes the following processors:
### RAL

- i.MX RT 1061
- i.MX RT 1062
The `imxrt-ral` crate is auto-generated from the checked-in SVD files, available in `imxrt-ral/svd`. It's checked into git, and you should always have whatever represents the latest auto-generated RAL. Generally, you should **not** manually change RAL source files; rather, you should describe changes in `imxrtral.py`, the Python script that auto-generates the RAL.

When developing the HAL(s) a quick way to check everything compiles, in the project root
To generate the RAL,

- Install Python 3. You'll need at least Python 3.6.
- Install the Python dependencies needed to generate the RAL: `pip3 install --user svdtools`. Alternatively, use the rules in the RAL's `Makefile` to create a virtual environment with the necessary dependencies: `make venv update-venv && source venv/bin/activate`.
- Run `make` in the `imxrt-ral` directory: `make -C imxrt-ral`. The auto-generation script might generate warnings; that's OK.

If everything went well, you should find that the `imxrt-ral/src` directory is populated with Rust files. If you made changes in `imxrtral.py`, you should see those changes reflected in the Rust files. The RAL can build by itself: `cd imxrt-ral && cargo check --features imxrt1062 --target thumbv7em-none-eabihf`.

If you add a SVD patch, or if you change something in `imxrtral.py`, you'll need to re-generate the RAL to realize the change.

### HAL

Make sure you've generated the RAL (see above). When developing the HAL, specify a feature flag from the command line. To check the HAL for `imxrt1062` processors, `cd imxrt-hal`, then

```
cargo check --features imxrt1062 --target thumbv7em-none-eabihf
```
cargo check --target thumbv7em-none-eabihf

### IOMUXC

The `imxrt-iomuxc` crate family does not require any feature flags, and it will build for your host. Consider using `--package` flags to build and test the crate family in one command:

```
cargo build --package=imxrt-iomuxc --package=imxrt-iomuxc-build
cargo test -p imxrt-iomuxc -p imxrt-iomuxc-build
```

### SVD Patches

To modify the RAL, you'll need to describe your change as an SVD patch. If you'd like to add patches to the i.MX RT SVD files, learn about [svdtools](https://github.com/stm32-rs/svdtools). Use some of the existing SVD patches as a guide.

### Testing

Our CI system ensures that the RAL and HAL(s) build for all processor variants. But, we can't automatically test against hardware! To test your changes on hardware, you'll need to test the RAL and the HAL(s) using another project, like a Rust BSP crate. Some BSP crates that use the `imxrt1060-hal` include
Our CI system ensures that the RAL and HAL builds for all processor variants. But, we can't automatically test against hardware! To test your changes on hardware, you'll need to test the RAL and the HAL using another project, like a Rust BSP crate. Some BSP crates that use the `imxrt-hal` include

- [the `imxrt1060evk-bsp` crate](https://github.com/imxrt-rs/imxrt1060evk-bsp)
- [the `teensy4-bsp` crate](https://github.com/mciantyre/teensy4-rs)
Expand All @@ -53,4 +76,4 @@ Follow the instructions in those projects to prepare an environment for testing

## Release Steps

To create a release of the RAL and HAL crates, see [RELEASE.md](docs/RELEASE.md).
To create a release of the RAL and HAL crates, see [RELEASE.md](docs/RELEASE.md).
4 changes: 2 additions & 2 deletions imxrt-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,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"
git = "https://github.com/dstric-aqueduct/imxrt-iomuxc.git"
branch = "v0.1.2/can"

[dev-dependencies.cortex-m-rt]
version = "0.6"
Expand Down
28 changes: 16 additions & 12 deletions imxrt-hal/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# imxrt1060-hal
# imxrt-hal

`imxrt1060-hal` is a Rust hardware abstraction layer that's specific to i.MX
RT 1060 processors. This includes some of the following processor parts:
This project provides a Rust HAL (hardware abstraction layer) for all NXP i.MX RT
microcontrollers based on the imxrt-ral crate.

- i.MX RT 1061
- i.MX RT 1062
A feature flag needs to be set for any of the supported i.MX RT SoC.

It is the successor to `imxrt-hal`, version 0.4, with `feature = "imxrt1062"`.
## What is it?

## Features
imxrt-hal is an experiment into a lightweight hardware abstraction layer. It
provides access to some of the peripherals of the i.MX RT series processors
from NXP using embedded-hal and other community driven hardware APIs.

The table below describes the optional features supported by `imxrt1060-hal`.
The main aims are fast compilation, compactness, and simplicity.

| Feature | Description |
| -------- | ---------------------------------- |
| `"rt"` | Runtime support with `cortex-m-rt` |
| `"rtic"` | Support for RTIC |
Please consider trying it out and contributing or leaving feedback!

## Goals

* Simple to use and hard to use incorrectly
* All peripherals and busses supported
* Support the entire i.MX RT Series with a single crate to maximize code reuse
7 changes: 0 additions & 7 deletions imxrt-hal/src/can/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,6 @@ impl PartialEq for Data {

impl Eq for Data {}

#[cfg(feature = "unstable-defmt")]
impl defmt::Format for Data {
fn format(&self, fmt: defmt::Formatter<'_>) {
self.as_ref().format(fmt)
}
}

macro_rules! data_from_array {
( $($len:literal),+ ) => {
$(
Expand Down
153 changes: 18 additions & 135 deletions imxrt-hal/src/can/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use ral::{modify_reg, read_reg, write_reg};

use crate::ccm;
use crate::iomuxc::consts::{Unsigned, U1, U2};
use crate::iomuxc::can;
use crate::ral;

use core::convert::Infallible;
use core::marker::PhantomData;

/// Error that indicates that an incoming message has been lost due to buffer overrun.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
pub struct OverrunError {
_priv: (),
}
Expand Down Expand Up @@ -52,7 +52,7 @@ impl Unclocked {
);

let clk_sel = match clock_select {
ccm::can::ClockSelect::Pll2 => ral::ccm::CSCMR2::CAN_CLK_SEL::RW::CAN_CLK_SEL_1,
ccm::can::ClockSelect::OSC => ral::ccm::CSCMR2::CAN_CLK_SEL::RW::CAN_CLK_SEL_1,
};

// Select clock, and commit prescalar
Expand Down Expand Up @@ -104,7 +104,14 @@ where

/// Builds a Can peripheral. The return
/// is a configured FlexCan peripheral running at 24MHz.
pub fn build(self) -> CAN<M> {
pub fn build<TX, RX>(self, mut tx: TX, mut rx: RX) -> CAN<M>
where
TX: can::Pin<Module = M, Signal = can::Tx>,
RX: can::Pin<Module = M, Signal = can::Rx>,
{
crate::iomuxc::can::prepare(&mut tx);
crate::iomuxc::can::prepare(&mut rx);

CAN::new(self.source_clock, self.reg)
}
}
Expand All @@ -118,24 +125,12 @@ pub struct CAN<M> {
_mailbox_reader_index: u8,
}

const CAN1_ADDR: u32 = 0x401d0000;
const CAN2_ADDR: u32 = 0x401d4000;

#[derive(Debug)]
pub struct MailboxData {
pub frame: Frame,
pub mailbox_number: u8,
}

#[inline]
fn constrain<T: PartialOrd>(value: T, min: T, max: T) -> T {
match value {
v if v < min => min,
v if v > max => max,
_ => value,
}
}

impl<M> CAN<M>
where
M: Unsigned,
Expand Down Expand Up @@ -198,8 +193,6 @@ where

pub fn begin(&mut self) {
self.set_ccm_ccg();
self.set_tx();
self.set_rx();

ral::modify_reg!(ral::can, self.reg, MCR, MDIS: MDIS_0);

Expand Down Expand Up @@ -255,10 +248,8 @@ where
}

pub fn base_address(&self) -> u32 {
match self.is_can1() {
true => CAN1_ADDR,
false => CAN2_ADDR,
}
let addr: *const ral::can::RegisterBlock = &*self.reg;
addr as u32
}

pub fn free(self) -> ral::can::Instance {
Expand Down Expand Up @@ -303,114 +294,6 @@ where
}
}

fn set_tx(&mut self) {
match self.instance_number() {
1 => {
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
SW_MUX_CTL_PAD_GPIO_AD_B1_08,
MUX_MODE: ALT2,
SION: ENABLED
)
};
unsafe {
write_reg!(
ral::iomuxc,
IOMUXC,
SW_PAD_CTL_PAD_GPIO_AD_B1_08,
0x10B0_u32
)
};
}
2 => {
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
SW_MUX_CTL_PAD_GPIO_AD_B0_02,
MUX_MODE: ALT0,
SION: ENABLED
)
};
unsafe {
write_reg!(
ral::iomuxc,
IOMUXC,
SW_PAD_CTL_PAD_GPIO_AD_B0_02,
0x10B0_u32
)
};
}
u => {
log::error!("Invalid Can instance (set_tx): {:?}", u);
}
}
}

fn set_rx(&mut self) {
match self.instance_number() {
1 => {
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
FLEXCAN1_RX_SELECT_INPUT,
DAISY: GPIO_AD_B1_09_ALT2
)
};
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
SW_MUX_CTL_PAD_GPIO_AD_B1_09,
MUX_MODE: ALT2,
SION: ENABLED
)
};
unsafe {
write_reg!(
ral::iomuxc,
IOMUXC,
SW_PAD_CTL_PAD_GPIO_AD_B1_09,
0x10B0_u32
)
};
}
2 => {
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
FLEXCAN2_RX_SELECT_INPUT,
DAISY: GPIO_AD_B0_03_ALT0
)
};
unsafe {
modify_reg!(
ral::iomuxc,
IOMUXC,
SW_MUX_CTL_PAD_GPIO_AD_B0_03,
MUX_MODE: ALT0,
SION: ENABLED
)
};
unsafe {
write_reg!(
ral::iomuxc,
IOMUXC,
SW_PAD_CTL_PAD_GPIO_AD_B0_03,
0x10B0_u32
)
};
}
u => {
log::error!("Invalid Can instance (set_rx): {:?}", u);
}
}
}

pub fn get_clock(&self) -> u32 {
self.source_clock.0
}
Expand Down Expand Up @@ -498,7 +381,7 @@ where
}

pub fn set_max_mailbox(&mut self, last: u8) {
let last = constrain(last, 1, 64) - 1;
let last = last.clamp(1, 64) - 1;
self.while_frozen(|this| {
let fifo_cleared = this.fifo_enabled();
this.disable_fifo();
Expand Down Expand Up @@ -643,7 +526,7 @@ where
let offset = this.mailbox_offset();
for i in 0..max_fifo_filters {
this.write_mailbox_idflt_tab(i as u8, Some(0x00));
if i < constrain(offset as usize, 0, 32) as u32 {
if i < offset.clamp(0, 32) as u32 {
this.write_mailbox_rximr(i as u8, Some(0x00));
}
}
Expand All @@ -654,7 +537,7 @@ where
let offset = this.mailbox_offset();
for i in 0..max_fifo_filters {
this.write_mailbox_idflt_tab(i as u8, Some(0xFFFFFFFF));
if i < constrain(offset, 0, 32) as u32 {
if i < offset.clamp(0, 32) as u32 {
this.write_mailbox_rximr(i as u8, Some(0x3FFFFFFF));
}
}
Expand All @@ -664,7 +547,7 @@ where
let offset = this.mailbox_offset();
for i in 0..max_fifo_filters {
this.write_mailbox_idflt_tab(i as u8, Some(0xFFFFFFFF));
if i < constrain(offset as usize, 0, 32) as u32 {
if i < offset.clamp(0, 32) as u32 {
this.write_mailbox_rximr(i as u8, Some(0x7FFF7FFF));
}
}
Expand Down Expand Up @@ -715,7 +598,7 @@ where
};
this.write_mailbox_idflt_tab(filter_id, Some(filter));
let offset = this.mailbox_offset();
if filter_id < constrain(offset, 0, 32) as u8 {
if filter_id < offset.clamp(0, 32) as u8 {
this.write_mailbox_rximr(filter_id, Some(mask));
}
write_reg!(ral::can, this.reg, RXFGMASK, 0x3FFFFFFF);
Expand Down Expand Up @@ -764,7 +647,7 @@ where
});
this.write_mailbox_idflt_tab(filter_id, Some(filter));
let offset = this.mailbox_offset();
if filter_id < constrain(offset as usize, 0, 32) as u8 {
if filter_id < offset.clamp(0, 32) as u8 {
this.write_mailbox_rximr(filter_id, Some(mask));
}
write_reg!(ral::can, this.reg, RXFGMASK, 0x7FFF7FFF);
Expand Down
Loading

0 comments on commit bff2cae

Please sign in to comment.