diff --git a/Cargo.lock b/Cargo.lock index 5c03ac3..0b464e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,6 +1320,7 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" name = "rp" version = "0.1.0" dependencies = [ + "cfg-if", "cortex-m", "cortex-m-rt", "crc16", diff --git a/Cargo.toml b/Cargo.toml index 672859a..3d5fa7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ rand = { version = "0.8.5", features = [ "std_rng", ], default-features = false } serde-json-core = "0.5.1" +cfg-if = "1.0.0" [patch.crates-io] embassy-executor = { git = "https://github.com/embassy-rs/embassy" } @@ -82,5 +83,10 @@ rust-mqtt = { path = "../rust-mqtt" } [build-dependencies] dotenvy = "0.15" +[features] +# With this feature enabled the cyw43 fiwmares are not included in the build and need to be manually flashed +# This helps speed up development +exclude_firmwares = [] + [profile.release] debug = true diff --git a/memory.x b/memory.x index 642ce71..9c3f0c5 100644 --- a/memory.x +++ b/memory.x @@ -1,5 +1,10 @@ MEMORY { - BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 - FLASH : ORIGIN = 0x10000100, LENGTH = 1024K - 0x100 - RAM : ORIGIN = 0x20000000, LENGTH = 256K + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 - 256k -8k + FW : ORIGIN = 0x101BE000, LENGTH = 256k + CLM : ORIGIN = 0x101FE000, LENGTH = 8k + RAM : ORIGIN = 0x20000000, LENGTH = 256K } + +__fw_start = ORIGIN(FW); +__clm_start = ORIGIN(CLM); diff --git a/src/main.rs b/src/main.rs index f2a5ea2..069ccff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -131,6 +131,36 @@ async fn uart_rx_task( } } +/// Get the cyw43 firmware blobs +/// +/// # Safety +/// When building with `exclude_firmwares` make sure to flash the firmwares using the following +/// commands: +/// ```bash +/// probe-rs download firmware/43439A0.bin --format bin --chip RP2040 --base-address 0x101BE000 +/// probe-rs download firmware/43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101FE000 +/// ``` +unsafe fn get_firmware() -> (&'static [u8], &'static [u8]) { + cfg_if::cfg_if! { + if #[cfg(feature = "exclude_firmwares")] { + // TODO: It would be nice if it could automatically get the correct size + extern "C" { + #[link_name = "__fw_start"] + static fw: [u8; 230321]; + #[link_name = "__clm_start"] + static clm: [u8; 4752]; + } + + (&fw, &clm) + } else { + let fw = include_bytes!("../firmware/43439A0.bin"); + let clm = include_bytes!("../firmware/43439A0_clm.bin"); + + (fw, clm) + } + } +} + #[embassy_executor::main] async fn main(spawner: Spawner) { info!("Starting..."); @@ -148,16 +178,6 @@ async fn main(spawner: Spawner) { spawner.spawn(uart_rx_task(rx, channel.sender())).unwrap(); - // === WIFI === - // To make flashing faster for development, you may want to flash the firmwares independently - // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: - // probe-rs download firmware/43439A0.bin --format bin --chip RP2040 --base-address 0x10100000 - // probe-rs download firmware/43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 - let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; - let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; - // let fw = include_bytes!("../firmware/43439A0.bin"); - // let clm = include_bytes!("../firmware/43439A0_clm.bin"); - let pwr = Output::new(p.PIN_23, Level::Low); let cs = Output::new(p.PIN_25, Level::High); @@ -172,6 +192,8 @@ async fn main(spawner: Spawner) { p.DMA_CH0, ); + let (fw, clm) = unsafe { get_firmware() }; + let state = make_static!(cyw43::State::new()); let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; spawner.spawn(wifi_task(runner)).unwrap();