From 55d0720b44cbdb2061866bf692de42e38e3d23b1 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 11 Dec 2025 12:04:09 +0100 Subject: feat: add support for buffered write mode for rram --- examples/nrf54l15/src/bin/nvmc.rs | 44 --------------------- examples/nrf54l15/src/bin/rramc.rs | 44 +++++++++++++++++++++ examples/nrf54l15/src/bin/rramc_buffered.rs | 59 +++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 44 deletions(-) delete mode 100644 examples/nrf54l15/src/bin/nvmc.rs create mode 100644 examples/nrf54l15/src/bin/rramc.rs create mode 100644 examples/nrf54l15/src/bin/rramc_buffered.rs (limited to 'examples') diff --git a/examples/nrf54l15/src/bin/nvmc.rs b/examples/nrf54l15/src/bin/nvmc.rs deleted file mode 100644 index f990604cd..000000000 --- a/examples/nrf54l15/src/bin/nvmc.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![no_std] -#![no_main] - -use defmt::{info, unwrap}; -use embassy_executor::Spawner; -use embassy_nrf::nvmc::{Nvmc, PAGE_SIZE}; -use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; -use {defmt_rtt as _, panic_probe as _}; - -#[embassy_executor::main] -async fn main(_spawner: Spawner) { - let p = embassy_nrf::init(Default::default()); - info!("Hello RRAMC NVMC!"); - - let mut f = Nvmc::new(p.RRAMC); - - const ADDR: u32 = 0x80000; - let mut buf = [0u8; 4]; - - info!("Reading..."); - unwrap!(f.read(ADDR, &mut buf)); - info!("Read: {=[u8]:x}", buf); - - info!("Erasing..."); - unwrap!(f.erase(ADDR, ADDR + PAGE_SIZE as u32)); - - info!("Reading..."); - unwrap!(f.read(ADDR, &mut buf)); - info!("Read: {=[u8]:x}", buf); - - info!("Writing..."); - // 16 B (128-bit) write minimum - let out: [u8; 16] = [ - 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, - ]; - unwrap!(f.write(ADDR, &out)); - - info!("Reading..."); - // Can read arbitrary sizes - for addr in (ADDR..ADDR + 16).step_by(4) { - unwrap!(f.read(addr, &mut buf)); - info!("Read: {=[u8]:x}", buf); - } -} diff --git a/examples/nrf54l15/src/bin/rramc.rs b/examples/nrf54l15/src/bin/rramc.rs new file mode 100644 index 000000000..f990604cd --- /dev/null +++ b/examples/nrf54l15/src/bin/rramc.rs @@ -0,0 +1,44 @@ +#![no_std] +#![no_main] + +use defmt::{info, unwrap}; +use embassy_executor::Spawner; +use embassy_nrf::nvmc::{Nvmc, PAGE_SIZE}; +use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + info!("Hello RRAMC NVMC!"); + + let mut f = Nvmc::new(p.RRAMC); + + const ADDR: u32 = 0x80000; + let mut buf = [0u8; 4]; + + info!("Reading..."); + unwrap!(f.read(ADDR, &mut buf)); + info!("Read: {=[u8]:x}", buf); + + info!("Erasing..."); + unwrap!(f.erase(ADDR, ADDR + PAGE_SIZE as u32)); + + info!("Reading..."); + unwrap!(f.read(ADDR, &mut buf)); + info!("Read: {=[u8]:x}", buf); + + info!("Writing..."); + // 16 B (128-bit) write minimum + let out: [u8; 16] = [ + 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, + ]; + unwrap!(f.write(ADDR, &out)); + + info!("Reading..."); + // Can read arbitrary sizes + for addr in (ADDR..ADDR + 16).step_by(4) { + unwrap!(f.read(addr, &mut buf)); + info!("Read: {=[u8]:x}", buf); + } +} diff --git a/examples/nrf54l15/src/bin/rramc_buffered.rs b/examples/nrf54l15/src/bin/rramc_buffered.rs new file mode 100644 index 000000000..06c9585ed --- /dev/null +++ b/examples/nrf54l15/src/bin/rramc_buffered.rs @@ -0,0 +1,59 @@ +#![no_std] +#![no_main] + +use defmt::{info, unwrap}; +use embassy_executor::Spawner; +use embassy_nrf::rramc::{Buffered, PAGE_SIZE, Rramc}; +use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + info!("Hello RRAMC NVMC!"); + + // Buffer 8 word lines + let mut f: Rramc<'_, Buffered<128>> = Rramc::new_buffered(p.RRAMC); + + const ADDR: u32 = 0x80000; + let mut buf = [0u8; 4]; + + info!("Reading..."); + unwrap!(f.read(ADDR, &mut buf)); + info!("Read: {=[u8]:x}", buf); + + info!("Erasing..."); + unwrap!(f.erase(ADDR, ADDR + PAGE_SIZE as u32)); + + info!("Reading..."); + unwrap!(f.read(ADDR, &mut buf)); + info!("Read: {=[u8]:x}", buf); + + info!("Writing..."); + // 16 B (128-bit) write minimum + let out: [u8; 256] = [ + 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, + 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, + 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, + 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, + 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, + 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, + 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, + 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, + 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xdd, 0xaa, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, + ]; + unwrap!(f.write(ADDR, &out)); + + info!("Reading..."); + // Can read arbitrary sizes + for addr in (ADDR..ADDR + 256).step_by(4) { + unwrap!(f.read(addr, &mut buf)); + info!("Read: {=[u8]:x}", buf); + } +} -- cgit From 7083411ca255efdfe0ebf9cfba8e889c38630aee Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 12 Dec 2025 00:42:31 +0100 Subject: examples/std: fix warning. --- examples/std/src/bin/net_ppp.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs index 82272c798..685dbf3d3 100644 --- a/examples/std/src/bin/net_ppp.rs +++ b/examples/std/src/bin/net_ppp.rs @@ -52,7 +52,7 @@ async fn ppp_task(stack: Stack<'static>, mut runner: Runner<'static>, port: Seri password: b"mypass", }; - runner + let r = runner .run(port, config, |ipv4| { let Some(addr) = ipv4.address else { warn!("PPP did not provide an IP address."); @@ -69,9 +69,10 @@ async fn ppp_task(stack: Stack<'static>, mut runner: Runner<'static>, port: Seri }); stack.set_config_v4(config); }) - .await - .unwrap(); - unreachable!() + .await; + match r { + Err(e) => panic!("{:?}", e), + } } #[embassy_executor::task] -- cgit From 17f0f4baa489d87d9862f9ab91dc73530daf5b3e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Dec 2025 15:42:46 -0800 Subject: [iMXRT] add a minimal DMA copy example While at that, also update the PACs to their latest versions. --- examples/mimxrt6/src/bin/dma.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 examples/mimxrt6/src/bin/dma.rs (limited to 'examples') diff --git a/examples/mimxrt6/src/bin/dma.rs b/examples/mimxrt6/src/bin/dma.rs new file mode 100644 index 000000000..b490efc6b --- /dev/null +++ b/examples/mimxrt6/src/bin/dma.rs @@ -0,0 +1,26 @@ +#![no_std] +#![no_main] + +extern crate embassy_imxrt_examples; + +use defmt::info; +use embassy_executor::Spawner; +use embassy_imxrt::dma::copy; +use {defmt_rtt as _, panic_probe as _}; + +const BUFLEN: usize = 1024; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("Test memory-to-memory DMA transfers"); + + let src = [0x55u8; BUFLEN]; + let mut dst = [0u8; BUFLEN]; + + unsafe { copy(p.DMA0_CH0, &src, &mut dst) }.await; + assert!(dst == src); + + info!("DMA copy succeeded"); +} -- cgit From b28b61dc4aeb772502c61e4b0d9091569fac4a40 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Dec 2025 15:56:27 -0800 Subject: [iMXRT] Add spi driver --- examples/mimxrt6/Cargo.toml | 2 ++ examples/mimxrt6/src/bin/spi-async.rs | 35 ++++++++++++++++++++++++ examples/mimxrt6/src/bin/spi.rs | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 examples/mimxrt6/src/bin/spi-async.rs create mode 100644 examples/mimxrt6/src/bin/spi.rs (limited to 'examples') diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml index dc09e97e7..ada112833 100644 --- a/examples/mimxrt6/Cargo.toml +++ b/examples/mimxrt6/Cargo.toml @@ -21,6 +21,8 @@ embedded-hal-async = "1.0.0" mimxrt600-fcb = "0.2.2" panic-probe = { version = "1.0.0", features = ["print-defmt"] } +embedded-hal-bus = "0.3.0" +is31fl3743b-driver = { version = "0.1.1", features = ["is_blocking"] } # cargo build/run [profile.dev] diff --git a/examples/mimxrt6/src/bin/spi-async.rs b/examples/mimxrt6/src/bin/spi-async.rs new file mode 100644 index 000000000..aa56f7c42 --- /dev/null +++ b/examples/mimxrt6/src/bin/spi-async.rs @@ -0,0 +1,35 @@ +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_imxrt::bind_interrupts; +use embassy_imxrt::flexcomm::spi::{InterruptHandler, Spi}; +use embassy_imxrt::peripherals::FLEXCOMM5; +use {defmt_rtt as _, embassy_imxrt_examples as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FLEXCOMM5 => InterruptHandler; +}); + +const BUFLEN: usize = 1024; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("Initializing SPI"); + + let mut spi = Spi::new_async(p.FLEXCOMM5, p.PIO1_3, p.PIO1_5, p.PIO1_4, Irqs, Default::default()); + + let mut rxbuf = [0x55; BUFLEN]; + let txbuf = [0xaa; BUFLEN]; + + for _ in 0..10 { + spi.async_transfer(&mut rxbuf, &txbuf).await.unwrap(); + assert!(rxbuf.iter().all(|b| *b == 0xaa)); + rxbuf.fill(0x55); + } + + info!("SPI transfers succeeded"); +} diff --git a/examples/mimxrt6/src/bin/spi.rs b/examples/mimxrt6/src/bin/spi.rs new file mode 100644 index 000000000..4854432e8 --- /dev/null +++ b/examples/mimxrt6/src/bin/spi.rs @@ -0,0 +1,51 @@ +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_imxrt::flexcomm::spi::Spi; +use embassy_imxrt::gpio; +use embassy_time::{Delay, Timer}; +use embedded_hal_bus::spi::ExclusiveDevice; +use is31fl3743b_driver::{CSy, Is31fl3743b, SWx}; +use {defmt_rtt as _, embassy_imxrt_examples as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_imxrt::init(Default::default()); + + info!("Initializing SPI"); + + let cs = gpio::Output::new( + p.PIO1_6, + gpio::Level::Low, + gpio::DriveMode::PushPull, + gpio::DriveStrength::Normal, + gpio::SlewRate::Standard, + ); + + let spi = Spi::new_blocking(p.FLEXCOMM5, p.PIO1_3, p.PIO1_5, p.PIO1_4, Default::default()); + let delay = Delay; + + // One SPI device only on the SPI bus + let spi_dev = ExclusiveDevice::new(spi, cs, delay).unwrap(); + + // Instantiate IS31FL3743B device + let mut driver = Is31fl3743b::new(spi_dev).unwrap(); + + // Enable phase delay to help reduce power noise + let _ = driver.enable_phase_delay(); + // Set global current, check method documentation for more info + let _ = driver.set_global_current(90); + + let _ = driver.set_led_peak_current_bulk(SWx::SW1, CSy::CS1, &[100; 11 * 18]); + + // Driver is fully set up, we can now start turning on LEDs! + // Create a white breathing effect + loop { + for brightness in (0..=255_u8).chain((0..=255).rev()) { + let _ = driver.set_led_brightness_bulk(SWx::SW1, CSy::CS1, &[brightness; 11 * 18]); + Timer::after_micros(1).await; + } + } +} -- cgit From b1fe9c6955ff857e3729a0bb4727247e050fb7ae Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:04:51 +0000 Subject: Add `run_until` function to std Executor as to support grafeul shutdown. --- examples/std/src/bin/tick_cancel.rs | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/std/src/bin/tick_cancel.rs (limited to 'examples') diff --git a/examples/std/src/bin/tick_cancel.rs b/examples/std/src/bin/tick_cancel.rs new file mode 100644 index 000000000..54e44790f --- /dev/null +++ b/examples/std/src/bin/tick_cancel.rs @@ -0,0 +1,47 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread; +use std::time::Duration; + +use embassy_executor::Executor; +use embassy_time::Timer; +use log::*; +use static_cell::StaticCell; + +#[embassy_executor::task] +async fn run() { + loop { + info!("tick"); + Timer::after_secs(1).await; + } +} + +static DONE: StaticCell = StaticCell::new(); +static EXECUTOR: StaticCell = StaticCell::new(); + +fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .format_timestamp_nanos() + .init(); + + let done = DONE.init(AtomicBool::new(false)); + let done_cb = || done.load(Ordering::Relaxed); + + let server_thread = thread::spawn(move || { + let executor = EXECUTOR.init(Executor::new()); + executor.run_until( + |spawner| { + spawner.spawn(run().unwrap()); + }, + done_cb, + ); + info!("Executor finished"); + }); + + thread::sleep(Duration::from_secs(5)); + + info!("Cancelling executor"); + done.store(true, Ordering::Relaxed); + + server_thread.join().unwrap(); +} -- cgit