Skip to content

Commit

Permalink
Merge branch 'rt1180-lpuart-dma'
Browse files Browse the repository at this point in the history
Just for testing the effects of TRDC on my debugger's ability to read
the CCM_OBS registers.
  • Loading branch information
mciantyre committed Jan 15, 2025
2 parents c994564 + 49d476a commit b3b004e
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
- name: Build examples
run: >
cargo build --features=board/imxrt1180evk-cm33 --target=thumbv8m.main-none-eabihf --release
--example=hal_led
--example=hal_led --example=hal_uart --example=async_dma_uart
# Run unit, integration tests.
#
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ imxrt1020 = ["imxrt-iomuxc/imxrt1020"]
imxrt1060 = ["imxrt-iomuxc/imxrt1060"]
imxrt1064 = ["imxrt-iomuxc/imxrt1060"]
imxrt1170 = ["imxrt-iomuxc/imxrt1170"]
imxrt1180 = ["imxrt-iomuxc/imxrt1180"]
imxrt1180 = ["imxrt-iomuxc/imxrt1180", "imxrt-dma/edma34"]

################
# Extra features
Expand Down Expand Up @@ -217,3 +217,7 @@ git = "https://github.com/imxrt-rs/imxrt-ral"

[patch.crates-io.imxrt-iomuxc]
git = "https://github.com/imxrt-rs/imxrt-iomuxc"

[patch.crates-io.imxrt-dma]
git = "https://github.com/mciantyre/imxrt-dma"
branch = "proto/edma34-const-gen-dma-inst"
3 changes: 3 additions & 0 deletions board/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ workspace = true
[build-dependencies.imxrt-rt]
workspace = true

[build-dependencies.cc]
version = "1"

[dependencies.imxrt-log]
workspace = true
optional = true
Expand Down
6 changes: 6 additions & 0 deletions board/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
16 * 1024 * 1024,
)
.rodata(imxrt_rt::Memory::Dtcm)
.stack(imxrt_rt::Memory::Ocram)
.build()?;
println!("cargo:rustc-cfg=board=\"imxrt1180evk-cm33\"");
println!("cargo:rustc-cfg=chip=\"imxrt1180\"");

cc::Build::new()
.object("ele_base_api.o")
.object("s3mu.o")
.compile("fsl");
}
_ => continue,
}
Expand Down
Binary file added board/ele_base_api.o
Binary file not shown.
Binary file added board/s3mu.o
Binary file not shown.
22 changes: 19 additions & 3 deletions board/src/imxrt1180evk-cm33.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! i.MX RT 1180 EVK, supporting the Cortex-M33.
use imxrt_hal::{self as hal, iomuxc};
use imxrt_iomuxc::imxrt1180::gpio_ad::*;
use imxrt_ral as ral;

Expand All @@ -12,7 +13,7 @@ use panic_probe as _;

pub unsafe fn configure() {}

/// TODO: I'm making this up. Don't make it up.
/// Runs on the OSC_RC_24M by default. Lucky guess!
pub const UART_CLK_FREQUENCY: u32 = 24_000_000;
/// TODO: I'm making this up. Don't make it up.
pub const LPI2C_CLK_FREQUENCY: u32 = 24_000_000;
Expand All @@ -22,9 +23,15 @@ pub const LPI2C_CLK_FREQUENCY: u32 = 24_000_000;
/// Managed through GPIO4_27.
pub type Led = imxrt_hal::rgpio::Output<GPIO_AD_27>;

const CONSOLE_INSTANCE: u8 = 1;
pub type Console = hal::lpuart::Lpuart<(), { CONSOLE_INSTANCE }>;

pub const CONSOLE_BAUD: hal::lpuart::Baud = hal::lpuart::Baud::compute(UART_CLK_FREQUENCY, 115200);

#[non_exhaustive]
pub struct Specifics {
pub led: Led,
pub console: Console,
}

impl Specifics {
Expand All @@ -33,6 +40,7 @@ impl Specifics {
IOMUXC,
IOMUXC_AON,
RGPIO4,
LPUART1,
mut ANADIG_OSC,
mut ANADIG_PLL,
mut ANADIG_PMU,
Expand All @@ -41,6 +49,7 @@ impl Specifics {
mut PHY_LDO,
..
} = unsafe { ral::Instances::instances() };
let mut pads = imxrt_hal::iomuxc::into_pads(IOMUXC, IOMUXC_AON);

imxrt_hal::ccm::init(
&mut ANADIG_OSC,
Expand All @@ -51,12 +60,19 @@ impl Specifics {
&mut PHY_LDO,
);

let pads = imxrt_hal::iomuxc::into_pads(IOMUXC, IOMUXC_AON);
iomuxc::alternate(&mut pads.gpio_aon.p08, 0); // LPUART1_TX
iomuxc::alternate(&mut pads.gpio_aon.p09, 0); // LPUART1_RX

let mut gpio4 = imxrt_hal::rgpio::Port::new(RGPIO4);
let led = gpio4.output(pads.gpio_ad.p27);

Specifics { led }
let mut console = hal::lpuart::Lpuart::without_pins(LPUART1);
console.disable(|console| {
console.set_baud(&CONSOLE_BAUD);
console.set_parity(None);
});

Specifics { led, console }
}
}

Expand Down
95 changes: 91 additions & 4 deletions board/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub struct Common {
/// Use [`GPT2_FREQUENCY`] to understand its frequency.
pub gpt2: hal::gpt::Gpt<2>,
/// DMA channels.
pub dma: [Option<hal::dma::channel::Channel>; hal::dma::CHANNEL_COUNT],
pub dma: [Option<hal::dma::Channel>; hal::dma::CHANNEL_COUNT],
/// Secure real-time counter.
///
/// Examples may enable the SRTC.
Expand Down Expand Up @@ -134,12 +134,99 @@ impl Common {

#[cfg(chip = "imxrt1180")]
#[non_exhaustive]
pub struct Common {}
pub struct Common {
/// DMA3 channels.
pub dma: [Option<hal::dma::channel::Channel<3>>; hal::dma::CHANNEL_COUNT],
}

#[cfg(chip = "imxrt1180")]
#[link(name = "fsl")]
unsafe extern "C" {
safe fn ELE_BaseAPI_GetFwStatus(s3m: *const (), status: &mut u32) -> i32;
safe fn ELE_BaseAPI_ReleaseRDC(s3m: *const (), rdc_id: u32, core_id: u32) -> i32;
}

#[cfg(chip = "imxrt1180")]
impl Common {
fn new() -> Self {
Self {}
// The 1189 RAL interface doesn't know about this.
const S3MU: *const () = 0x47540000 as _;

let mut scratch = 0;
// Is EdgeLock alive and happy with our firmware?
while ELE_BaseAPI_GetFwStatus(S3MU, &mut scratch) != 0 {}
// EdgeLock, please give us (the CM33, magic? 0x01) the TRDC1 (magic? 0x71).
while ELE_BaseAPI_ReleaseRDC(S3MU, 0x74, 0x01) != 0 {}

// Safety: Nothing else is running during board setup.
unsafe {
// The eDMA domain access controller will bypass its own
// domain ID. Instead, it will uses ID from the accessing
// bus. That's us, the CM33.
//
// Some constants in the RAL / from the SVD are useless...
ral::modify_reg!(ral::trdc1, ral::trdc1::TRDC1, MDA_W0_2_DFMT1,
PA: 2, // Use the bus' privilege attribute.
SA: 2, // Use the bus' security attribute.
DIDB: 1, // Let the DMA engine "masquerade" as a processor.
VLD: VALID, // Everything we just set is valid.
);

// We want all block controllers and all region controllers to accept
// all accesses. Too bad the SVDs didn't cluster these registers / raltool
// didn't codgen good.
const ALLOW_ALL: u32 = 0b0111_0111_0111_0111;

ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC0, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC1, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC2, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC3, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC4, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC5, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC6, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC0_GLBAC7, ALLOW_ALL);

ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC0, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC1, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC2, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC3, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC4, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC5, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC6, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MRC1_GLBAC7, ALLOW_ALL);

ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC0, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC1, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC2, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC3, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC4, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC5, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC6, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC0_MEMN_GLBAC7, ALLOW_ALL);

ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC0, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC1, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC2, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC3, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC4, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC5, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC6, ALLOW_ALL);
ral::write_reg!(ral::trdc1, ral::trdc1::TRDC1, MBC1_MEMN_GLBAC7, ALLOW_ALL);

// Enable the TRDC. Debugging reveals that this is already
// set once we gain access to the TRDC, so this doesn't
// seem necessary.
ral::modify_reg!(ral::trdc1, ral::trdc1::TRDC1, TRDC_CR,
GVLDM: 1,
GVLDB: 1,
GVLDR: 1,
);
}

// let dma = [const { None }; 32];
// Safety: Only executes once per program.
let dma = unsafe { hal::dma::channels3() };
Self { dma }
}
}
/// Board entrypoint.
Expand Down Expand Up @@ -308,7 +395,7 @@ pub mod blocking {
/// features. Then, simply define the default backend in your module.
#[cfg(feature = "imxrt-log")]
pub mod logging {
use crate::hal::{dma::channel::Channel, lpuart::Lpuart, usbd::Instances};
use crate::hal::{dma::Channel, lpuart::Lpuart, usbd::Instances};
pub use imxrt_log::Poller;
pub const BACKEND: Backend = crate::board_impl::DEFAULT_LOGGING_BACKEND;

Expand Down
2 changes: 1 addition & 1 deletion logging/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use filters::Filters;
use crate::{Poller, BUFFER};

#[cfg(feature = "lpuart")]
use imxrt_hal::{dma::channel::Channel, lpuart::Lpuart};
use imxrt_hal::{dma::Channel, lpuart::Lpuart};

/// Logging configuration
///
Expand Down
6 changes: 3 additions & 3 deletions logging/src/lpuart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
//! is OK from the first phase.
use imxrt_hal::{
dma::{channel, peripheral::Destination},
dma::{channel, peripheral::Destination, Channel},
lpuart::{Direction, Lpuart},
};
use static_cell::StaticCell;

pub(crate) struct Backend {
consumer: crate::Consumer,
channel: channel::Channel,
channel: Channel,
}

impl Backend {
Expand Down Expand Up @@ -114,7 +114,7 @@ impl Backend {
/// Panics if called more than once.
pub(crate) fn init<P, const LPUART: u8>(
mut lpuart: Lpuart<P, LPUART>,
mut channel: channel::Channel,
mut channel: Channel,
consumer: crate::Consumer,
interrupts: crate::Interrupts,
) -> &'static mut Backend {
Expand Down
Loading

0 comments on commit b3b004e

Please sign in to comment.