From e670477522d8c9e7a554f2b606939241d3e7f0fc Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Mon, 19 Aug 2024 21:29:31 +0100 Subject: [PATCH] Runs on the Pico 2. Tested showing 640x480@4bpp images and running the neotracker with DAMAGE.MOD. --- .cargo/config.toml | 10 ++- .github/workflows/build.yml | 14 ++-- .github/workflows/clippy.yml | 4 +- .vscode/launch.json | 2 +- Cargo.lock | 123 +++++++++++++++++++++-------------- Cargo.toml | 3 +- memory.x | 76 +++++++++++++++------- src/main.rs | 29 +++++---- src/multicore.rs | 6 +- 9 files changed, 162 insertions(+), 105 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 4df83e6..f088549 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,8 +1,6 @@ -[target.thumbv6m-none-eabi] -# This will make a UF2 and copy it to the RP2040's Mass Storage Device bootloader -# runner = "elf2uf2-rs -d" -# This will flash over SWD with any compatible probe it finds. -runner = "probe-rs run --chip RP2040 --speed 10000" +[target.thumbv8m.main-none-eabihf] +# This will load the binary with picotool +runner = "picotool load -v -u -x -t elf" rustflags = [ # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 @@ -16,7 +14,7 @@ rustflags = [ ] [build] -target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +target = "thumbv8m.main-none-eabihf" # Cortex-M33 [env] DEFMT_LOG = { value = "info" } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae73b7e..1abe710 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,15 +24,15 @@ jobs: run: | rustup toolchain install stable --profile minimal --no-self-update rustup default stable - rustup target add thumbv6m-none-eabi + rustup target add thumbv8m.main-none-eabihf echo CARGO_INCREMENTAL=0 >> $GITHUB_ENV echo CARGO_TERM_COLOR=always >> $GITHUB_ENV - name: Build neotron-pico-bios run: | cargo build --release --verbose - mv ./target/thumbv6m-none-eabi/release/neotron-pico-bios ./target/thumbv6m-none-eabi/release/neotron-pico-bios.elf - elf2uf2-rs ./target/thumbv6m-none-eabi/release/neotron-pico-bios.elf + mv ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.elf + # elf2uf2-rs ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.elf - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -41,15 +41,15 @@ jobs: name: Artifacts if-no-files-found: error path: | - ./target/thumbv6m-none-eabi/release/neotron-pico-bios.elf - ./target/thumbv6m-none-eabi/release/neotron-pico-bios.uf2 + ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.elf + ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.uf2 - name: Upload files to Release if: github.event_name == 'push' && startswith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v1 with: files: | - ./target/thumbv6m-none-eabi/release/neotron-pico-bios.elf - ./target/thumbv6m-none-eabi/release/neotron-pico-bios.uf2 + ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.elf + ./target/thumbv8m.main-none-eabihf/release/neotron-pico-bios.uf2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 93c0ebe..1d58f64 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -19,8 +19,8 @@ jobs: - name: Add targets/components run: | rustup component add clippy - rustup target add thumbv6m-none-eabi + rustup target add thumbv8m.main-none-eabihf - name: Run Clippy run: | - cargo clippy --target=thumbv6m-none-eabi --all-features + cargo clippy --target=thumbv8m.main-none-eabihf --all-features diff --git a/.vscode/launch.json b/.vscode/launch.json index 3e0e5ee..9dbefef 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,7 +14,7 @@ "coreConfigs": [ { // Change this to the binary you want to debug - "programBinary": "${workspaceFolder}/target/thumbv6m-none-eabi/release/neotron-pico-bios", + "programBinary": "${workspaceFolder}/target/thumbv8m.main-none-eabihf/release/neotron-pico-bios", "rttEnabled": true } ], diff --git a/Cargo.lock b/Cargo.lock index 7b1e40b..43e271e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,15 +152,6 @@ dependencies = [ "syn 2.0.93", ] -[[package]] -name = "crc-any" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73" -dependencies = [ - "debug-helper", -] - [[package]] name = "critical-section" version = "1.2.0" @@ -173,12 +164,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "debug-helper" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" - [[package]] name = "defmt" version = "0.3.10" @@ -343,9 +328,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "fixedbitset" -version = "0.4.2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "frunk" @@ -441,9 +426,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heapless" @@ -476,9 +461,9 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "indexmap" -version = "2.7.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -504,6 +489,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "lalrpop" version = "0.19.12" @@ -515,7 +509,7 @@ dependencies = [ "diff", "ena", "is-terminal", - "itertools", + "itertools 0.10.5", "lalrpop-util", "petgraph", "regex", @@ -649,7 +643,7 @@ dependencies = [ "embedded-sdmmc", "fugit", "grounded", - "heapless 0.7.17", + "heapless 0.8.0", "mcp794xx", "neotron-bmc-commands", "neotron-bmc-protocol", @@ -659,8 +653,7 @@ dependencies = [ "pio", "pio-proc", "portable-atomic", - "rp2040-boot2", - "rp2040-hal", + "rp235x-hal", "shared-bus", "tlv320aic23", "vte", @@ -753,9 +746,9 @@ checksum = "ed089a1fbffe3337a1a345501c981f1eb1e47e69de5a40e852433e12953c3174" [[package]] name = "petgraph" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +checksum = "c94eb96835f05ec51384814c9b2daef83f68486f67a0e2e9680e0f698dca808e" dependencies = [ "fixedbitset", "indexmap", @@ -950,6 +943,37 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "riscv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", +] + +[[package]] +name = "riscv-rt" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0d35e32cf1383183e8885d8a9aa4402a087fd094dc34c2cb6df6687d0229dfe" +dependencies = [ + "riscv", + "riscv-rt-macros", +] + +[[package]] +name = "riscv-rt-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30f19a85fe107b65031e0ba8ec60c34c2494069fe910d6c297f5e7cb5a6f76d0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + [[package]] name = "rp-binary-info" version = "0.1.0" @@ -966,22 +990,14 @@ dependencies = [ ] [[package]] -name = "rp2040-boot2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21" -dependencies = [ - "crc-any", -] - -[[package]] -name = "rp2040-hal" -version = "0.11.0" +name = "rp235x-hal" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb79a4590775204387f334672e6f79c0d734d0a159da23d60677b3c10fa1245" +checksum = "ed1714150c427d4be4022ff92dbf26a7e69c4eb7c1eba151c5752299c7c7f165" dependencies = [ "bitfield 0.14.0", "cortex-m", + "cortex-m-rt", "critical-section", "defmt", "embedded-dma", @@ -992,37 +1008,40 @@ dependencies = [ "embedded-io", "frunk", "fugit", - "itertools", + "gcd", + "itertools 0.13.0", "nb 1.1.0", "paste", "pio", "rand_core", + "riscv", + "riscv-rt", "rp-binary-info", "rp-hal-common", - "rp2040-hal-macros", - "rp2040-pac", + "rp235x-hal-macros", + "rp235x-pac", + "sha2-const-stable", "usb-device", "vcell", "void", ] [[package]] -name = "rp2040-hal-macros" +name = "rp235x-hal-macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86479063e497efe1ae81995ef9071f54fd1c7427e04d6c5b84cde545ff672a5e" +checksum = "74edd7a5979e9763bbb98e9746e711bac7464ee3397af7288e6c288ff0d3c764" dependencies = [ - "cortex-m-rt", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.93", ] [[package]] -name = "rp2040-pac" -version = "0.6.0" +name = "rp235x-pac" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83cbcd3f7a0ca7bbe61dc4eb7e202842bee4e27b769a7bf3a4a72fa399d6e404" +checksum = "5ffcb6931deee4242886b5a1df62db5e2555b0eb6ae1e8be101f3ea3e58e65c6" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1090,6 +1109,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "shared-bus" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 17965d8..7cb2e97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,7 @@ pc-keyboard = "0.7.0" # PS/2 scancode decoding pio = "0.2.1" # RP2040 PIO assembler pio-proc = "0.2" # Macros for RP2040 PIO assembler portable-atomic = { version = "1.10.0", features = ["critical-section"] } # Atomic CAS for non-CAS CPUs -rp2040-boot2 = "0.3.0" # For the RP2040 bootloader -rp2040-hal = { version = "0.11", features = [ "defmt", "rt", "critical-section-impl", "rom-func-cache" ] } # The Raspberry Pi RP2040 HAL (so we can turn defmt on) +rp235x-hal = { version = "0.2", features = [ "defmt", "rt", "critical-section-impl", "rom-func-cache" ] } # The Raspberry Pi RP2350 HAL shared-bus = "0.3.1" # I2C Bus Sharing tlv320aic23 = "0.1.0" # CODEC register control diff --git a/memory.x b/memory.x index adb7213..0591c12 100644 --- a/memory.x +++ b/memory.x @@ -8,24 +8,18 @@ MEMORY { /* - * This is bootloader for the RP2040. It must live at the start of the - external flash chip. + * The Pico 2 has 4096 KiB of external Flash Memory. We allow ourselves 128 + * KiB for the BIOS, leaving the rest for the OS and any user applications. */ - BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000000, LENGTH = 128K /* - * The Pico has 2048 KiB of external Flash Memory. We allow ourselves 128 - * KiB for the BIOS, leaving the rest - * for the OS and any user applications. + * This is the remainder of the 4096 KiB flash chip. */ - FLASH : ORIGIN = 0x10000100, LENGTH = 128K - 0x100 - /* - * This is the remainder of the 2048 KiB flash chip. - */ - FLASH_OS : ORIGIN = 0x10020000, LENGTH = 2048K - 128K + FLASH_OS : ORIGIN = 0x10020000, LENGTH = 4096K - 128K /* * This is the bottom of the four striped banks of SRAM in the RP2040. */ - RAM_OS : ORIGIN = 0x20000000, LENGTH = 0x42000 - 0x9690 + RAM_OS : ORIGIN = 0x20000000, LENGTH = 0x82000 - 0x9690 /* * This is the top of the four striped banks of SRAM in the RP2040, plus * SRAM_BANK4 and SRAM_BANK5. @@ -36,7 +30,7 @@ MEMORY { * 0x9690 should be the (size of .data + size of .bss + size of .uninit + * 0x2000 for the stack). */ - RAM : ORIGIN = 0x20042000 - 0x9690, LENGTH = 0x9690 + RAM : ORIGIN = 0x20082000 - 0x9690, LENGTH = 0x9690 } /* @@ -48,17 +42,55 @@ _ram_os_start = ORIGIN(RAM_OS); _ram_os_len = LENGTH(RAM_OS); SECTIONS { - /* ### RP2040 Boot loader */ - .boot2 ORIGIN(BOOT2) : + /* ### 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) { - KEEP(*(.boot2)); - } > BOOT2 + /* 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; - /* ### Neotron OS */ - .flash_os ORIGIN(FLASH_OS) : +SECTIONS { + /* ### Boot ROM extra info + * + * Goes after everything in our program, so it can contain a signature. + */ + .end_block : ALIGN(4) { - KEEP(*(.flash_os)); - } > FLASH_OS -} INSERT BEFORE .text; + __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/src/main.rs b/src/main.rs index 8f3f6be..d15e4e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,7 +83,7 @@ use hal::{ }; use panic_probe as _; use pc_keyboard::{KeyCode, ScancodeSet}; -use rp2040_hal as hal; +use rp235x_hal as hal; // Other Neotron Crates use mutex::NeoMutex; @@ -172,7 +172,7 @@ struct Hardware { /// The time we started up at, in microseconds since the Neotron epoch bootup_at: Duration, /// A 1 MHz Timer - timer: hal::timer::Timer, + timer: hal::timer::Timer, /// the state of our SD Card card_state: CardState, /// Tracks all the clocks in the RP2040 @@ -235,12 +235,10 @@ struct Pins { // Static and Const Data // ----------------------------------------------------------------------------- -/// The linker will place this boot block at the start of our program image. We -/// need this to help the ROM bootloader get our code up and running. -#[link_section = ".boot2"] -#[no_mangle] +/// Tell the Boot ROM about our application +#[link_section = ".start_block"] #[used] -pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; +pub static IMAGE_DEF: hal::block::ImageDef = hal::block::ImageDef::secure_exe(); /// Version string auto-generated in build.rs static VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/version.txt")); @@ -386,7 +384,7 @@ fn main() -> ! { .map_err(|_x| false) .unwrap(); // Step 2. Configure watchdog tick generation to tick over every microsecond. - watchdog.enable_tick_generation((XOSC_CRYSTAL_FREQ / 1_000_000) as u8); + watchdog.enable_tick_generation((XOSC_CRYSTAL_FREQ / 1_000_000) as u16); // Step 3. Create a clocks manager. let mut clocks = hal::clocks::ClocksManager::new(pp.CLOCKS); // Step 4. Set up the system PLL. @@ -452,7 +450,7 @@ fn main() -> ! { sio.gpio_bank0, pp.SPI0, pp.I2C1, - pp.TIMER, + pp.TIMER0, pp.PIO1, clocks, delay, @@ -849,7 +847,7 @@ impl Hardware { sio: hal::sio::SioGpioBank0, spi: pac::SPI0, i2c: pac::I2C1, - timer: pac::TIMER, + timer: pac::TIMER0, pio1: pac::PIO1, clocks: ClocksManager, delay: cortex_m::delay::Delay, @@ -897,7 +895,7 @@ impl Hardware { } let mut external_rtc = rtc::Rtc::new(proxy); - let timer = hal::timer::Timer::new(timer, resets, &clocks); + let timer = hal::timer::Timer::new_timer0(timer, resets, &clocks); // Do a conversion from external RTC time (chrono::NaiveDateTime) to a format we can track let ticks_at_boot_us = match external_rtc.get_time(i2c.acquire_i2c()) { Ok(time) => { @@ -2628,8 +2626,13 @@ extern "C" fn power_control(power_mode: common::FfiPowerMode) -> ! { Ok(common::PowerMode::Bootloader) => { // Reboot to USB bootloader with no GPIOs and both USB interfaces // enabled. - hal::rom_data::reset_to_usb_boot(0, 0); - core::unreachable!() + hal::reboot::reboot( + hal::reboot::RebootKind::BootSel { + picoboot_disabled: false, + msd_disabled: false, + }, + hal::reboot::RebootArch::Arm, + ); } _ => { // Anything else causes a reset diff --git a/src/multicore.rs b/src/multicore.rs index bc04710..350f750 100644 --- a/src/multicore.rs +++ b/src/multicore.rs @@ -118,8 +118,8 @@ pub fn launch_core1_with_stack( (CORE1_ENTRY_FUNCTION.as_ptr() as usize as u32) + 1, ]; - let enabled = cortex_m::peripheral::NVIC::is_enabled(crate::pac::Interrupt::SIO_IRQ_PROC0); - cortex_m::peripheral::NVIC::mask(crate::pac::Interrupt::SIO_IRQ_PROC0); + let enabled = cortex_m::peripheral::NVIC::is_enabled(crate::pac::Interrupt::SIO_IRQ_FIFO); + cortex_m::peripheral::NVIC::mask(crate::pac::Interrupt::SIO_IRQ_FIFO); 'outer: loop { for cmd in cmd_sequence.iter() { @@ -154,7 +154,7 @@ pub fn launch_core1_with_stack( } if enabled { - unsafe { cortex_m::peripheral::NVIC::unmask(crate::pac::Interrupt::SIO_IRQ_PROC0) }; + unsafe { cortex_m::peripheral::NVIC::unmask(crate::pac::Interrupt::SIO_IRQ_FIFO) }; } defmt::debug!("Waiting for Core 1 to start...");