diff --git a/examples/rp23/Cargo.toml b/examples/rp23/Cargo.toml index c2817380c8..087f6fd698 100644 --- a/examples/rp23/Cargo.toml +++ b/examples/rp23/Cargo.toml @@ -56,7 +56,7 @@ portable-atomic = { version = "1.5", features = ["critical-section"] } log = "0.4" pio-proc = "0.2" pio = "0.2.1" -rand = { version = "0.8.5", default-features = false, features = ["small_rng"]} +rand = { version = "0.8.5", default-features = false } embedded-sdmmc = "0.7.0" bt-hci = { version = "0.1.0", default-features = false, features = ["defmt"] } diff --git a/examples/rp23/src/bin/trng.rs b/examples/rp23/src/bin/trng.rs index d82f013523..e146baa2e5 100644 --- a/examples/rp23/src/bin/trng.rs +++ b/examples/rp23/src/bin/trng.rs @@ -1,20 +1,17 @@ -//! This example test the RP Pico on board LED. -//! -//! It does not work with the RP Pico W board. See wifi_blinky.rs. +//! This example shows TRNG usage #![no_std] #![no_main] use defmt::*; use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; use embassy_rp::block::ImageDef; -use embassy_rp::{bind_interrupts, gpio}; +use embassy_rp::gpio::{Level, Output}; use embassy_rp::peripherals::TRNG; use embassy_rp::trng::Trng; use embassy_time::Timer; -use gpio::{Level, Output}; -use rand::{RngCore, SeedableRng}; -use rand::rngs::SmallRng; +use rand::RngCore; use {defmt_rtt as _, panic_probe as _}; #[link_section = ".start_block"] @@ -38,25 +35,30 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main] async fn main(_spawner: Spawner) { let peripherals = embassy_rp::init(Default::default()); + // Initialize the TRNG with default configuration let mut trng = Trng::new(peripherals.TRNG, Irqs, embassy_rp::trng::Config::default()); // A buffer to collect random bytes in. let mut randomness = [0u8; 58]; - // A small_rng pseudo RNG initialized from TRNG - let mut small_rng = SmallRng::from_rng(trng).unwrap(); - loop { + let mut led = Output::new(peripherals.PIN_25, Level::Low); + loop { trng.fill_bytes(&mut randomness).await; info!("Random bytes async {}", &randomness); - trng.blocking_fill_bytes(&mut randomness).await; + trng.blocking_fill_bytes(&mut randomness); info!("Random bytes blocking {}", &randomness); let random_u32 = trng.next_u32(); let random_u64 = trng.next_u64(); info!("Random u32 {} u64 {}", random_u32, random_u64); - small_rng.fill_bytes(&mut randomness); - info!("Small rng {}", &randomness); + // Random number of blinks between 0 and 31 + let blinks = random_u32 % 32; + for _ in 0..blinks { + led.set_high(); + Timer::after_millis(20).await; + led.set_low(); + Timer::after_millis(20).await; + } Timer::after_millis(1000).await; - } } diff --git a/tests/rp23/.cargo/config.toml b/tests/rp23/.cargo/config.toml new file mode 100644 index 0000000000..e6463be2de --- /dev/null +++ b/tests/rp23/.cargo/config.toml @@ -0,0 +1,23 @@ +[unstable] +# enabling these breaks the float tests during linking, with intrinsics +# duplicated between embassy-rp and compilter_builtins +#build-std = ["core"] +#build-std-features = ["panic_immediate_abort"] + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "picotool load -u -v -x -t elf" +#runner = "teleprobe client run" +#runner = "teleprobe local run --chip RP2040 --elf" + +rustflags = [ + # Code-size optimizations. + #"-Z", "trap-unreachable=no", + "-C", "inline-threshold=5", + "-C", "no-vectorize-loops", +] + +[build] +target = "thumbv8m.main-none-eabihf" + +[env] +DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info" diff --git a/tests/rp23/Cargo.toml b/tests/rp23/Cargo.toml new file mode 100644 index 0000000000..d7fc9a0c92 --- /dev/null +++ b/tests/rp23/Cargo.toml @@ -0,0 +1,81 @@ +[package] +edition = "2021" +name = "embassy-rp2350-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + + +[dependencies] +teleprobe-meta = "1.1" + +embassy-embedded-hal = { version = "0.2.0", path = "../../embassy-embedded-hal", features = ["defmt"] } +embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } +embassy-executor = { version = "0.6.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-rp = { version = "0.2.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] } +embassy-usb = { version = "0.3.0", path = "../../embassy-usb", features = ["defmt"] } +embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns"] } +embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } +embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } +embassy-usb-logger = { version = "0.2.0", path = "../../embassy-usb-logger" } +cyw43 = { version = "0.2.0", path = "../../cyw43", features = ["defmt", "firmware-logs", "bluetooth"] } +cyw43-pio = { version = "0.2.0", path = "../../cyw43-pio", features = ["defmt"] } + +defmt = "0.3" +defmt-rtt = "0.4.1" +fixed = "1.23.1" +fixed-macro = "1.2" + +# for web request example +reqwless = { version = "0.12.0", features = ["defmt",]} +serde = { version = "1.0.203", default-features = false, features = ["derive"] } +serde-json-core = "0.5.1" + +# for assign resources example +assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" } + +#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m = { version = "0.7.6", features = ["inline-asm"] } +cortex-m-rt = "0.7.0" +critical-section = "1.1" +panic-probe = { version = "0.3", features = ["print-defmt"] } +display-interface-spi = "0.4.1" +embedded-graphics = "0.7.1" +st7789 = "0.6.1" +display-interface = "0.4.1" +byte-slice-cast = { version = "1.2.0", default-features = false } +smart-leds = "0.3.0" +heapless = "0.8" +usbd-hid = "0.8.1" + +embedded-hal-1 = { package = "embedded-hal", version = "1.0" } +embedded-hal-async = "1.0" +embedded-hal-bus = { version = "0.1", features = ["async"] } +embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } +embedded-storage = { version = "0.3" } +static_cell = "2.1" +portable-atomic = { version = "1.5", features = ["critical-section"] } +log = "0.4" +pio-proc = "0.2" +pio = "0.2.1" +rand = { version = "0.8.5", default-features = false } +embedded-sdmmc = "0.7.0" + +bt-hci = { version = "0.1.0", default-features = false, features = ["defmt"] } +trouble-host = { version = "0.1.0", features = ["defmt", "gatt"] } + +[profile.release] +debug = 2 + +[profile.dev] +lto = true +opt-level = "z" + +[patch.crates-io] +trouble-host = { git = "https://github.com/embassy-rs/trouble.git", rev = "4b8c0f499b34e46ca23a56e2d1640ede371722cf" } +embassy-executor = { path = "../../embassy-executor" } +embassy-sync = { path = "../../embassy-sync" } +embassy-futures = { path = "../../embassy-futures" } +embassy-time = { path = "../../embassy-time" } +embassy-time-driver = { path = "../../embassy-time-driver" } +embassy-embedded-hal = { path = "../../embassy-embedded-hal" } diff --git a/tests/rp23/build.rs b/tests/rp23/build.rs new file mode 100644 index 0000000000..feb19ddad9 --- /dev/null +++ b/tests/rp23/build.rs @@ -0,0 +1,39 @@ +use std::error::Error; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +use std::{env, fs}; +// fn main() -> Result<(), Box> { +// let out = PathBuf::from(env::var("OUT_DIR").unwrap()); +// fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); +// println!("cargo:rustc-link-search={}", out.display()); +// println!("cargo:rerun-if-changed=link_ram.x"); +// +// println!("cargo:rustc-link-arg-bins=--nmagic"); +// println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); +// println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +// println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); +// +// Ok(()) +// } + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/tests/rp23/memory.x b/tests/rp23/memory.x new file mode 100644 index 0000000000..7774920622 --- /dev/null +++ b/tests/rp23/memory.x @@ -0,0 +1,74 @@ +MEMORY { + /* + * The RP2350 has either external or internal flash. + * + * 2 MiB is a safe default here, although a Pico 2 has 4 MiB. + */ + FLASH : ORIGIN = 0x10000000, LENGTH = 2048K + /* + * RAM consists of 8 banks, SRAM0-SRAM7, with a striped mapping. + * This is usually good for performance, as it distributes load on + * those banks evenly. + */ + RAM : ORIGIN = 0x20000000, LENGTH = 512K + /* + * RAM banks 8 and 9 use a direct mapping. They can be used to have + * memory areas dedicated for some specific job, improving predictability + * of access times. + * Example: Separate stacks for core0 and core1. + */ + SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K + SRAM5 : ORIGIN = 0x20081000, LENGTH = 4K +} + +SECTIONS { + /* ### Boot ROM info + * + * Goes after .vector_table, to keep it in the first 4K of flash + * where the Boot ROM (and picotool) can find it + */ + .start_block : ALIGN(4) + { + __start_block_addr = .; + KEEP(*(.start_block)); + } > FLASH + +} INSERT AFTER .vector_table; + +/* move .text to start /after/ the boot info */ +_stext = ADDR(.start_block) + SIZEOF(.start_block); + +SECTIONS { + /* ### Picotool 'Binary Info' Entries + * + * Picotool looks through this block (as we have pointers to it in our + * header) to find interesting information. + */ + .bi_entries : ALIGN(4) + { + /* We put this in the header */ + __bi_entries_start = .; + /* Here are the entries */ + KEEP(*(.bi_entries)); + /* Keep this block a nice round size */ + . = ALIGN(4); + /* We put this in the header */ + __bi_entries_end = .; + } > FLASH +} INSERT AFTER .text; + +SECTIONS { + /* ### Boot ROM extra info + * + * Goes after everything in our program, so it can contain a signature. + */ + .end_block : ALIGN(4) + { + __end_block_addr = .; + KEEP(*(.end_block)); + } > FLASH + +} INSERT AFTER .uninit; + +PROVIDE(start_to_end = __end_block_addr - __start_block_addr); +PROVIDE(end_to_start = __start_block_addr - __end_block_addr); diff --git a/tests/rp23/src/bin/trng.rs b/tests/rp23/src/bin/trng.rs new file mode 100644 index 0000000000..e68a1e3466 --- /dev/null +++ b/tests/rp23/src/bin/trng.rs @@ -0,0 +1,58 @@ +//! A simple test confirming that using trng produces some results. Doesn't test the quality of +//! the randomness provided. +#![no_std] +#![no_main] +teleprobe_meta::target!(b"rpi-pico"); + +use defmt::{assert_ne, *}; +use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; +use embassy_rp::block::ImageDef; +use embassy_rp::gpio::{Level, Output}; +use embassy_rp::peripherals::TRNG; +use embassy_rp::trng::Trng; +use embassy_time::Timer; +use rand::RngCore; +use {defmt_rtt as _, panic_probe as _}; + +#[link_section = ".start_block"] +#[used] +pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe(); + +// Program metadata for `picotool info` +#[link_section = ".bi_entries"] +#[used] +pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [ + embassy_rp::binary_info::rp_program_name!(c"example"), + embassy_rp::binary_info::rp_cargo_version!(), + embassy_rp::binary_info::rp_program_description!(c"Blinky"), + embassy_rp::binary_info::rp_program_build_attribute!(), +]; + +bind_interrupts!(struct Irqs { + TRNG_IRQ => embassy_rp::trng::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let peripherals = embassy_rp::init(Default::default()); + + // Initialize the TRNG with default configuration + let mut trng = Trng::new(peripherals.TRNG, Irqs, embassy_rp::trng::Config::default()); + // A buffer to collect random bytes in. + let mut randomness = [0u8; 58]; + + trng.fill_bytes(&mut randomness).await; + assert_ne!(randomness, [0u8; 58]); + + randomness = [0u8; 58]; + trng.blocking_fill_bytes(&mut randomness); + assert_ne!(randomness, [0u8; 58]); + + let random_u32 = trng.next_u32(); + let random_u64 = trng.next_u64(); + + assert_ne!(random_u32 as u64, random_u64); + + cortex_m::asm::bkpt(); +}