From 1d46f55bddf402c33143959e1ad26af59bb15855 Mon Sep 17 00:00:00 2001 From: i509VCB Date: Mon, 21 Jul 2025 20:29:34 -0500 Subject: nxp: Add mimxrt1062 support The examples in this case are designed for the IMXRT1060-EVK. The same chip is used in the Teensy 4.0/1, but that will probably get its own set of examples due to some differences such as the FCB. --- .vscode/settings.json | 1 + ci.sh | 4 +- embassy-nxp/Cargo.toml | 5 +- embassy-nxp/build.rs | 10 +- embassy-nxp/src/chips/mimxrt1062.rs | 282 +++++++++++++++++++++++++++++ embassy-nxp/src/gpio/rt1xxx.rs | 62 ++++++- embassy-nxp/src/lib.rs | 1 + examples/mimxrt1062-evk/.cargo/config.toml | 8 + examples/mimxrt1062-evk/Cargo.toml | 29 +++ examples/mimxrt1062-evk/build.rs | 12 ++ examples/mimxrt1062-evk/src/bin/blinky.rs | 25 +++ examples/mimxrt1062-evk/src/bin/button.rs | 36 ++++ examples/mimxrt1062-evk/src/lib.rs | 60 ++++++ 13 files changed, 522 insertions(+), 13 deletions(-) create mode 100644 embassy-nxp/src/chips/mimxrt1062.rs create mode 100644 examples/mimxrt1062-evk/.cargo/config.toml create mode 100644 examples/mimxrt1062-evk/Cargo.toml create mode 100644 examples/mimxrt1062-evk/build.rs create mode 100644 examples/mimxrt1062-evk/src/bin/blinky.rs create mode 100644 examples/mimxrt1062-evk/src/bin/button.rs create mode 100644 examples/mimxrt1062-evk/src/lib.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 070e8fbd3..6edd9312a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -37,6 +37,7 @@ // "examples/nrf5340/Cargo.toml", // "examples/nrf-rtos-trace/Cargo.toml", // "examples/mimxrt1011/Cargo.toml", + // "examples/mimxrt1062-evk/Cargo.toml", // "examples/rp/Cargo.toml", // "examples/std/Cargo.toml", // "examples/stm32c0/Cargo.toml", diff --git a/ci.sh b/ci.sh index e225bc7c9..1a9a1d209 100755 --- a/ci.sh +++ b/ci.sh @@ -181,7 +181,8 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf --features lpc55,defmt \ - --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv7em-none-eabihf --features mimxrt1011,defmt,time-driver-pit \ + --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv7em-none-eabihf --features mimxrt1011,rt,defmt,time-driver-pit \ + --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv7em-none-eabihf --features mimxrt1062,rt,defmt,time-driver-pit \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c1104dgs20,defmt,time-driver-any \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3507pm,defmt,time-driver-any \ --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g3519pz,defmt,time-driver-any \ @@ -266,6 +267,7 @@ cargo batch \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ --- build --release --manifest-path examples/mimxrt1011/Cargo.toml --target thumbv7em-none-eabihf --artifact-dir out/examples/mimxrt1011 \ + --- build --release --manifest-path examples/mimxrt1062-evk/Cargo.toml --target thumbv7em-none-eabihf --artifact-dir out/examples/mimxrt1062-evk \ --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \ --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \ --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \ diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index 625906183..293791d34 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml @@ -17,13 +17,13 @@ embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-util ## Chip dependencies lpc55-pac = { version = "0.5.0", optional = true } -nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "1e010dbe75ab0e14dd908e4646391403414c8a8e" } +nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "be4dd0936c20d5897364a381b1d95a99514c1e7e" } imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] } [build-dependencies] cfg_aliases = "0.2.1" -nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "1e010dbe75ab0e14dd908e4646391403414c8a8e", features = ["metadata"], optional = true } +nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "be4dd0936c20d5897364a381b1d95a99514c1e7e", features = ["metadata"], optional = true } proc-macro2 = "1.0.95" quote = "1.0.15" @@ -58,3 +58,4 @@ _time_driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils"] #! ### Chip selection features lpc55 = ["dep:lpc55-pac"] mimxrt1011 = ["nxp-pac/mimxrt1011", "_rt1xxx", "dep:imxrt-rt"] +mimxrt1062 = ["nxp-pac/mimxrt1062", "_rt1xxx", "dep:imxrt-rt"] diff --git a/embassy-nxp/build.rs b/embassy-nxp/build.rs index 6c10d0e69..f3c062c87 100644 --- a/embassy-nxp/build.rs +++ b/embassy-nxp/build.rs @@ -32,10 +32,12 @@ fn main() { .to_ascii_lowercase(); cfg_aliases! { - rt1xxx: { feature = "mimxrt1011" }, - gpio1: { feature = "mimxrt1011" }, - gpio2: { feature = "mimxrt1011" }, - gpio5: { feature = "mimxrt1011" }, + rt1xxx: { any(feature = "mimxrt1011", feature = "mimxrt1062") }, + gpio1: { any(feature = "mimxrt1011", feature = "mimxrt1062") }, + gpio2: { any(feature = "mimxrt1011", feature = "mimxrt1062") }, + gpio3: { feature = "mimxrt1062" }, + gpio4: { feature = "mimxrt1062" }, + gpio5: { any(feature = "mimxrt1011", feature = "mimxrt1062") }, } eprintln!("chip: {chip_name}"); diff --git a/embassy-nxp/src/chips/mimxrt1062.rs b/embassy-nxp/src/chips/mimxrt1062.rs new file mode 100644 index 000000000..ef153bd66 --- /dev/null +++ b/embassy-nxp/src/chips/mimxrt1062.rs @@ -0,0 +1,282 @@ +// This must be imported so that __preinit is defined. +use imxrt_rt as _; +pub use nxp_pac as pac; + +embassy_hal_internal::peripherals! { + // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other + // peripheral types (e.g. I2C). + GPIO_AD_B0_00, + GPIO_AD_B0_01, + GPIO_AD_B0_02, + GPIO_AD_B0_03, + GPIO_AD_B0_04, + GPIO_AD_B0_05, + GPIO_AD_B0_06, + GPIO_AD_B0_07, + GPIO_AD_B0_08, + GPIO_AD_B0_09, + GPIO_AD_B0_10, + GPIO_AD_B0_11, + GPIO_AD_B0_12, + GPIO_AD_B0_13, + GPIO_AD_B0_14, + GPIO_AD_B0_15, + GPIO_AD_B1_00, + GPIO_AD_B1_01, + GPIO_AD_B1_02, + GPIO_AD_B1_03, + GPIO_AD_B1_04, + GPIO_AD_B1_05, + GPIO_AD_B1_06, + GPIO_AD_B1_07, + GPIO_AD_B1_08, + GPIO_AD_B1_09, + GPIO_AD_B1_10, + GPIO_AD_B1_11, + GPIO_AD_B1_12, + GPIO_AD_B1_13, + GPIO_AD_B1_14, + GPIO_AD_B1_15, + GPIO_B0_00, + GPIO_B0_01, + GPIO_B0_02, + GPIO_B0_03, + GPIO_B0_04, + GPIO_B0_05, + GPIO_B0_06, + GPIO_B0_07, + GPIO_B0_08, + GPIO_B0_09, + GPIO_B0_10, + GPIO_B0_11, + GPIO_B0_12, + GPIO_B0_13, + GPIO_B0_14, + GPIO_B0_15, + GPIO_B1_00, + GPIO_B1_01, + GPIO_B1_02, + GPIO_B1_03, + GPIO_B1_04, + GPIO_B1_05, + GPIO_B1_06, + GPIO_B1_07, + GPIO_B1_08, + GPIO_B1_09, + GPIO_B1_10, + GPIO_B1_11, + GPIO_B1_12, + GPIO_B1_13, + GPIO_B1_14, + GPIO_B1_15, + GPIO_EMC_00, + GPIO_EMC_01, + GPIO_EMC_02, + GPIO_EMC_03, + GPIO_EMC_04, + GPIO_EMC_05, + GPIO_EMC_06, + GPIO_EMC_07, + GPIO_EMC_08, + GPIO_EMC_09, + GPIO_EMC_10, + GPIO_EMC_11, + GPIO_EMC_12, + GPIO_EMC_13, + GPIO_EMC_14, + GPIO_EMC_15, + GPIO_EMC_16, + GPIO_EMC_17, + GPIO_EMC_18, + GPIO_EMC_19, + GPIO_EMC_20, + GPIO_EMC_21, + GPIO_EMC_22, + GPIO_EMC_23, + GPIO_EMC_24, + GPIO_EMC_25, + GPIO_EMC_26, + GPIO_EMC_27, + GPIO_EMC_28, + GPIO_EMC_29, + GPIO_EMC_30, + GPIO_EMC_31, + GPIO_EMC_32, + GPIO_EMC_33, + GPIO_EMC_34, + GPIO_EMC_35, + GPIO_EMC_36, + GPIO_EMC_37, + GPIO_EMC_38, + GPIO_EMC_39, + GPIO_EMC_40, + GPIO_EMC_41, + GPIO_SD_B0_00, + GPIO_SD_B0_01, + GPIO_SD_B0_02, + GPIO_SD_B0_03, + GPIO_SD_B0_04, + GPIO_SD_B0_05, + GPIO_SD_B1_00, + GPIO_SD_B1_01, + GPIO_SD_B1_02, + GPIO_SD_B1_03, + GPIO_SD_B1_04, + GPIO_SD_B1_05, + GPIO_SD_B1_06, + GPIO_SD_B1_07, + GPIO_SD_B1_08, + GPIO_SD_B1_09, + GPIO_SD_B1_10, + GPIO_SD_B1_11, + WAKEUP, + PMIC_ON_REQ, + PMIC_STBY_REQ, +} + +impl_gpio! { + // GPIO Bank 1 + GPIO_AD_B0_00(Gpio1, 0); + GPIO_AD_B0_01(Gpio1, 1); + GPIO_AD_B0_02(Gpio1, 2); + GPIO_AD_B0_03(Gpio1, 3); + GPIO_AD_B0_04(Gpio1, 4); + GPIO_AD_B0_05(Gpio1, 5); + GPIO_AD_B0_06(Gpio1, 6); + GPIO_AD_B0_07(Gpio1, 7); + GPIO_AD_B0_08(Gpio1, 8); + GPIO_AD_B0_09(Gpio1, 9); + GPIO_AD_B0_10(Gpio1, 10); + GPIO_AD_B0_11(Gpio1, 11); + GPIO_AD_B0_12(Gpio1, 12); + GPIO_AD_B0_13(Gpio1, 13); + GPIO_AD_B0_14(Gpio1, 14); + GPIO_AD_B0_15(Gpio1, 15); + GPIO_AD_B1_00(Gpio1, 16); + GPIO_AD_B1_01(Gpio1, 17); + GPIO_AD_B1_02(Gpio1, 18); + GPIO_AD_B1_03(Gpio1, 19); + GPIO_AD_B1_04(Gpio1, 20); + GPIO_AD_B1_05(Gpio1, 21); + GPIO_AD_B1_06(Gpio1, 22); + GPIO_AD_B1_07(Gpio1, 23); + GPIO_AD_B1_08(Gpio1, 24); + GPIO_AD_B1_09(Gpio1, 25); + GPIO_AD_B1_10(Gpio1, 26); + GPIO_AD_B1_11(Gpio1, 27); + GPIO_AD_B1_12(Gpio1, 28); + GPIO_AD_B1_13(Gpio1, 29); + GPIO_AD_B1_14(Gpio1, 30); + GPIO_AD_B1_15(Gpio1, 31); + + // GPIO Bank 2 + GPIO_B0_00(Gpio2, 0); + GPIO_B0_01(Gpio2, 1); + GPIO_B0_02(Gpio2, 2); + GPIO_B0_03(Gpio2, 3); + GPIO_B0_04(Gpio2, 4); + GPIO_B0_05(Gpio2, 5); + GPIO_B0_06(Gpio2, 6); + GPIO_B0_07(Gpio2, 7); + GPIO_B0_08(Gpio2, 8); + GPIO_B0_09(Gpio2, 9); + GPIO_B0_10(Gpio2, 10); + GPIO_B0_11(Gpio2, 11); + GPIO_B0_12(Gpio2, 12); + GPIO_B0_13(Gpio2, 13); + GPIO_B0_14(Gpio2, 14); + GPIO_B0_15(Gpio2, 15); + GPIO_B1_00(Gpio2, 16); + GPIO_B1_01(Gpio2, 17); + GPIO_B1_02(Gpio2, 18); + GPIO_B1_03(Gpio2, 19); + GPIO_B1_04(Gpio2, 20); + GPIO_B1_05(Gpio2, 21); + GPIO_B1_06(Gpio2, 22); + GPIO_B1_07(Gpio2, 23); + GPIO_B1_08(Gpio2, 24); + GPIO_B1_09(Gpio2, 25); + GPIO_B1_10(Gpio2, 26); + GPIO_B1_11(Gpio2, 27); + GPIO_B1_12(Gpio2, 28); + GPIO_B1_13(Gpio2, 29); + GPIO_B1_14(Gpio2, 30); + GPIO_B1_15(Gpio2, 31); + + // GPIO Bank 4 (EMC is 4, then 3) + GPIO_EMC_00(Gpio4, 0); + GPIO_EMC_01(Gpio4, 1); + GPIO_EMC_02(Gpio4, 2); + GPIO_EMC_03(Gpio4, 3); + GPIO_EMC_04(Gpio4, 4); + GPIO_EMC_05(Gpio4, 5); + GPIO_EMC_06(Gpio4, 6); + GPIO_EMC_07(Gpio4, 7); + GPIO_EMC_08(Gpio4, 8); + GPIO_EMC_09(Gpio4, 9); + GPIO_EMC_10(Gpio4, 10); + GPIO_EMC_11(Gpio4, 11); + GPIO_EMC_12(Gpio4, 12); + GPIO_EMC_13(Gpio4, 13); + GPIO_EMC_14(Gpio4, 14); + GPIO_EMC_15(Gpio4, 15); + GPIO_EMC_16(Gpio4, 16); + GPIO_EMC_17(Gpio4, 17); + GPIO_EMC_18(Gpio4, 18); + GPIO_EMC_19(Gpio4, 19); + GPIO_EMC_20(Gpio4, 20); + GPIO_EMC_21(Gpio4, 21); + GPIO_EMC_22(Gpio4, 22); + GPIO_EMC_23(Gpio4, 23); + GPIO_EMC_24(Gpio4, 24); + GPIO_EMC_25(Gpio4, 25); + GPIO_EMC_26(Gpio4, 26); + GPIO_EMC_27(Gpio4, 27); + GPIO_EMC_28(Gpio4, 28); + GPIO_EMC_29(Gpio4, 29); + GPIO_EMC_30(Gpio4, 30); + GPIO_EMC_31(Gpio4, 31); + + // GPIO Bank 3 + GPIO_EMC_32(Gpio3, 18); + GPIO_EMC_33(Gpio3, 19); + GPIO_EMC_34(Gpio3, 20); + GPIO_EMC_35(Gpio3, 21); + GPIO_EMC_36(Gpio3, 22); + GPIO_EMC_37(Gpio3, 23); + GPIO_EMC_38(Gpio3, 24); + GPIO_EMC_39(Gpio3, 25); + GPIO_EMC_40(Gpio3, 26); + GPIO_EMC_41(Gpio3, 27); + GPIO_SD_B0_00(Gpio3, 12); + GPIO_SD_B0_01(Gpio3, 13); + GPIO_SD_B0_02(Gpio3, 14); + GPIO_SD_B0_03(Gpio3, 15); + GPIO_SD_B0_04(Gpio3, 16); + GPIO_SD_B0_05(Gpio3, 17); + GPIO_SD_B1_00(Gpio3, 0); + GPIO_SD_B1_01(Gpio3, 1); + GPIO_SD_B1_02(Gpio3, 2); + GPIO_SD_B1_03(Gpio3, 3); + GPIO_SD_B1_04(Gpio3, 4); + GPIO_SD_B1_05(Gpio3, 5); + GPIO_SD_B1_06(Gpio3, 6); + GPIO_SD_B1_07(Gpio3, 7); + GPIO_SD_B1_08(Gpio3, 8); + GPIO_SD_B1_09(Gpio3, 9); + GPIO_SD_B1_10(Gpio3, 10); + GPIO_SD_B1_11(Gpio3, 11); + + WAKEUP(Gpio5, 0); + PMIC_ON_REQ(Gpio5, 1); + PMIC_STBY_REQ(Gpio5, 2); +} + +pub(crate) mod _generated { + #![allow(dead_code)] + #![allow(unused_imports)] + #![allow(non_snake_case)] + #![allow(missing_docs)] + + include!(concat!(env!("OUT_DIR"), "/_generated.rs")); +} diff --git a/embassy-nxp/src/gpio/rt1xxx.rs b/embassy-nxp/src/gpio/rt1xxx.rs index 9c58e8a7d..1d60a0d51 100644 --- a/embassy-nxp/src/gpio/rt1xxx.rs +++ b/embassy-nxp/src/gpio/rt1xxx.rs @@ -12,11 +12,11 @@ use nxp_pac::iomuxc::vals::Pus; use crate::chip::{mux_address, pad_address}; use crate::pac::common::{Reg, RW}; +use crate::pac::gpio::Gpio; #[cfg(feature = "rt")] use crate::pac::interrupt; use crate::pac::iomuxc::regs::{Ctl, MuxCtl}; -#[cfg(gpio5)] -use crate::pac::{self, gpio::Gpio}; +use crate::pac::{self}; /// The GPIO pin level for pins set on "Digital" mode. #[derive(Debug, Eq, PartialEq, Clone, Copy)] @@ -110,6 +110,14 @@ pub enum Bank { #[cfg(gpio2)] Gpio2, + /// Bank 3 + #[cfg(gpio3)] + Gpio3, + + /// Bank 4 + #[cfg(gpio4)] + Gpio4, + /// Bank 5 #[cfg(gpio5)] Gpio5, @@ -642,6 +650,10 @@ const GPIO_MUX_MODE: u8 = 0b101; static GPIO1_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; #[cfg(gpio2)] static GPIO2_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; +#[cfg(gpio3)] +static GPIO3_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; +#[cfg(gpio4)] +static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; #[cfg(gpio5)] static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; @@ -658,6 +670,10 @@ pub(crate) trait SealedPin: Sized { Bank::Gpio1 => pac::GPIO1, #[cfg(gpio2)] Bank::Gpio2 => pac::GPIO2, + #[cfg(gpio3)] + Bank::Gpio3 => pac::GPIO3, + #[cfg(gpio4)] + Bank::Gpio4 => pac::GPIO4, #[cfg(gpio5)] Bank::Gpio5 => pac::GPIO5, } @@ -687,6 +703,10 @@ pub(crate) trait SealedPin: Sized { Bank::Gpio1 => &GPIO1_WAKERS[self.pin_number() as usize], #[cfg(gpio2)] Bank::Gpio2 => &GPIO2_WAKERS[self.pin_number() as usize], + #[cfg(gpio3)] + Bank::Gpio3 => &GPIO3_WAKERS[self.pin_number() as usize], + #[cfg(gpio4)] + Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], #[cfg(gpio5)] Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], } @@ -870,25 +890,55 @@ fn irq_handler(block: Gpio, wakers: &[AtomicWaker; 32], high_bits: bool) { } } -#[cfg(all(feature = "mimxrt1011", feature = "rt"))] +#[cfg(all(any(feature = "mimxrt1011", feature = "mimxrt1062"), feature = "rt"))] #[interrupt] fn GPIO1_COMBINED_0_15() { irq_handler(pac::GPIO1, &GPIO1_WAKERS, false); } -#[cfg(all(feature = "mimxrt1011", feature = "rt"))] +#[cfg(all(any(feature = "mimxrt1011", feature = "mimxrt1062"), feature = "rt"))] #[interrupt] fn GPIO1_COMBINED_16_31() { irq_handler(pac::GPIO1, &GPIO1_WAKERS, true); } -#[cfg(all(feature = "mimxrt1011", feature = "rt"))] +#[cfg(all(any(feature = "mimxrt1011", feature = "mimxrt1062"), feature = "rt"))] #[interrupt] fn GPIO2_COMBINED_0_15() { irq_handler(pac::GPIO2, &GPIO2_WAKERS, false); } -#[cfg(all(feature = "mimxrt1011", feature = "rt"))] +#[cfg(all(feature = "mimxrt1062", feature = "rt"))] +#[interrupt] +fn GPIO2_COMBINED_16_31() { + irq_handler(pac::GPIO2, &GPIO2_WAKERS, true); +} + +#[cfg(all(feature = "mimxrt1062", feature = "rt"))] +#[interrupt] +fn GPIO3_COMBINED_0_15() { + irq_handler(pac::GPIO3, &GPIO3_WAKERS, false); +} + +#[cfg(all(feature = "mimxrt1062", feature = "rt"))] +#[interrupt] +fn GPIO3_COMBINED_16_31() { + irq_handler(pac::GPIO3, &GPIO3_WAKERS, true); +} + +#[cfg(all(feature = "mimxrt1062", feature = "rt"))] +#[interrupt] +fn GPIO4_COMBINED_0_15() { + irq_handler(pac::GPIO4, &GPIO4_WAKERS, false); +} + +#[cfg(all(feature = "mimxrt1062", feature = "rt"))] +#[interrupt] +fn GPIO4_COMBINED_16_31() { + irq_handler(pac::GPIO4, &GPIO4_WAKERS, true); +} + +#[cfg(all(any(feature = "mimxrt1011", feature = "mimxrt1062"), feature = "rt"))] #[interrupt] fn GPIO5_COMBINED_0_15() { irq_handler(pac::GPIO5, &GPIO5_WAKERS, false); diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs index a715770c4..5e77fc0db 100644 --- a/embassy-nxp/src/lib.rs +++ b/embassy-nxp/src/lib.rs @@ -14,6 +14,7 @@ mod time_driver; // This mod MUST go last, so that it sees all the `impl_foo!` macros #[cfg_attr(feature = "lpc55", path = "chips/lpc55.rs")] #[cfg_attr(feature = "mimxrt1011", path = "chips/mimxrt1011.rs")] +#[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")] mod chip; #[cfg(feature = "unstable-pac")] diff --git a/examples/mimxrt1062-evk/.cargo/config.toml b/examples/mimxrt1062-evk/.cargo/config.toml new file mode 100644 index 000000000..ca4c606dc --- /dev/null +++ b/examples/mimxrt1062-evk/.cargo/config.toml @@ -0,0 +1,8 @@ +[target.thumbv7em-none-eabihf] +runner = 'probe-rs run --chip MIMXRT1060' + +[build] +target = "thumbv7em-none-eabihf" # Cortex-M7 + +[env] +DEFMT_LOG = "trace" diff --git a/examples/mimxrt1062-evk/Cargo.toml b/examples/mimxrt1062-evk/Cargo.toml new file mode 100644 index 000000000..430a26b41 --- /dev/null +++ b/examples/mimxrt1062-evk/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "embassy-imxrt1062-evk-examples" +version = "0.1.0" +edition = "2021" +license = "MIT or Apache-2.0" + +[dependencies] +cortex-m = { version = "0.7.7", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.3" +defmt = "1.0.1" +defmt-rtt = "1.0.0" + +embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } +embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } +embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["defmt", "mimxrt1062", "unstable-pac", "time-driver-pit"] } +embassy-time = { version = "0.4", path = "../../embassy-time", features = ["defmt", ] } # "defmt-timestamp-uptime" +embassy-sync = { version = "0.7.0", path = "../../embassy-sync", features = ["defmt"] } +embedded-hal-1 = { package = "embedded-hal", version = "1.0" } +embedded-hal-async = "1.0.0" + +imxrt-boot-gen = { version = "0.3.4", features = ["imxrt1060"] } +panic-probe = { version = "1.0.0", features = ["print-defmt"] } +panic-semihosting = "0.6.0" + +[build-dependencies] +imxrt-rt = { version = "0.1.7", features = ["device"] } + +[profile.release] +debug = 2 diff --git a/examples/mimxrt1062-evk/build.rs b/examples/mimxrt1062-evk/build.rs new file mode 100644 index 000000000..e0e0d547e --- /dev/null +++ b/examples/mimxrt1062-evk/build.rs @@ -0,0 +1,12 @@ +use imxrt_rt::{Family, RuntimeBuilder}; + +fn main() { + RuntimeBuilder::from_flexspi(Family::Imxrt1060, 8 * 1024 * 1024) + .build() + .unwrap(); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); + // Not link.x, as imxrt-rt needs to do some special things + println!("cargo:rustc-link-arg-bins=-Timxrt-link.x"); +} diff --git a/examples/mimxrt1062-evk/src/bin/blinky.rs b/examples/mimxrt1062-evk/src/bin/blinky.rs new file mode 100644 index 000000000..b6d90d94d --- /dev/null +++ b/examples/mimxrt1062-evk/src/bin/blinky.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_nxp::gpio::{Level, Output}; +use embassy_time::Timer; +// Must include `embassy_imxrt1062_evk_examples` to ensure the FCB gets linked. +use {defmt_rtt as _, embassy_imxrt1062_evk_examples as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + let p = embassy_nxp::init(Default::default()); + info!("Hello world!"); + + let led = p.GPIO_AD_B0_08; + let mut led = Output::new(led, Level::Low); + + loop { + Timer::after_millis(500).await; + + info!("Toggle"); + led.toggle(); + } +} diff --git a/examples/mimxrt1062-evk/src/bin/button.rs b/examples/mimxrt1062-evk/src/bin/button.rs new file mode 100644 index 000000000..d60fa3dac --- /dev/null +++ b/examples/mimxrt1062-evk/src/bin/button.rs @@ -0,0 +1,36 @@ +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_nxp::gpio::{Input, Level, Output, Pull}; +use {defmt_rtt as _, embassy_imxrt1062_evk_examples as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) -> ! { + let p = embassy_nxp::init(Default::default()); + info!("Hello world!"); + + // User LED (D8) + let led = p.GPIO_AD_B0_08; + // User button (SW5) + let button = p.WAKEUP; + let mut button = Input::new(button, Pull::Up100K); + let mut led = Output::new(led, Level::Low); + led.set_high(); + + loop { + button.wait_for_falling_edge().await; + + info!("Toggled"); + led.toggle(); + + // Software debounce. + button.wait_for_rising_edge().await; + + // Stabilization. + for _ in 0..100_000 { + cortex_m::asm::nop(); + } + } +} diff --git a/examples/mimxrt1062-evk/src/lib.rs b/examples/mimxrt1062-evk/src/lib.rs new file mode 100644 index 000000000..3f99f9db3 --- /dev/null +++ b/examples/mimxrt1062-evk/src/lib.rs @@ -0,0 +1,60 @@ +//! FlexSPI configuration block (FCB) for the iMXRT1060-EVK +//! +//! This uses IS25WP QuadSPI flash. + +#![no_std] + +use imxrt_boot_gen::flexspi::opcodes::sdr::*; +use imxrt_boot_gen::flexspi::{self, FlashPadType, ReadSampleClockSource, SerialClockFrequency, SerialFlashRegion, *}; +use imxrt_boot_gen::serial_flash::*; +pub use nor::ConfigurationBlock; + +const SEQ_READ: Sequence = SequenceBuilder::new() + .instr(Instr::new(CMD, Pads::One, 0xEB)) + .instr(Instr::new(RADDR, Pads::Four, 0x18)) + .instr(Instr::new(DUMMY, Pads::Four, 0x06)) + .instr(Instr::new(READ, Pads::Four, 0x04)) + .build(); +const SEQ_READ_STATUS: Sequence = SequenceBuilder::new() + .instr(Instr::new(CMD, Pads::One, 0x05)) + .instr(Instr::new(READ, Pads::One, 0x04)) + .build(); +const SEQ_WRITE_ENABLE: Sequence = SequenceBuilder::new().instr(Instr::new(CMD, Pads::One, 0x06)).build(); +const SEQ_ERASE_SECTOR: Sequence = SequenceBuilder::new() + .instr(Instr::new(CMD, Pads::One, 0x20)) + .instr(Instr::new(RADDR, Pads::One, 0x18)) + .build(); +const SEQ_PAGE_PROGRAM: Sequence = SequenceBuilder::new() + .instr(Instr::new(CMD, Pads::One, 0x02)) + .instr(Instr::new(RADDR, Pads::One, 0x18)) + .instr(Instr::new(WRITE, Pads::One, 0x04)) + .build(); +const SEQ_CHIP_ERASE: Sequence = SequenceBuilder::new().instr(Instr::new(CMD, Pads::One, 0x60)).build(); + +const LUT: LookupTable = LookupTable::new() + .command(Command::Read, SEQ_READ) + .command(Command::ReadStatus, SEQ_READ_STATUS) + .command(Command::WriteEnable, SEQ_WRITE_ENABLE) + .command(Command::EraseSector, SEQ_ERASE_SECTOR) + .command(Command::PageProgram, SEQ_PAGE_PROGRAM) + .command(Command::ChipErase, SEQ_CHIP_ERASE); + +const COMMON_CONFIGURATION_BLOCK: flexspi::ConfigurationBlock = flexspi::ConfigurationBlock::new(LUT) + .version(Version::new(1, 4, 0)) + .read_sample_clk_src(ReadSampleClockSource::LoopbackFromDQSPad) + .cs_hold_time(3) + .cs_setup_time(3) + .controller_misc_options(0x10) + .serial_flash_pad_type(FlashPadType::Quad) + .serial_clk_freq(SerialClockFrequency::MHz133) + .flash_size(SerialFlashRegion::A1, 8 * 1024 * 1024); + +pub const SERIAL_NOR_CONFIGURATION_BLOCK: nor::ConfigurationBlock = + nor::ConfigurationBlock::new(COMMON_CONFIGURATION_BLOCK) + .page_size(256) + .sector_size(4096) + .ip_cmd_serial_clk_freq(nor::SerialClockFrequency::MHz30); + +#[no_mangle] +#[cfg_attr(all(target_arch = "arm", target_os = "none"), link_section = ".fcb")] +pub static FLEXSPI_CONFIGURATION_BLOCK: nor::ConfigurationBlock = SERIAL_NOR_CONFIGURATION_BLOCK; -- cgit