From 29c325a94c0103fd7d6888125324f18e15619fb8 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Tue, 13 Jun 2023 21:32:12 +0200 Subject: [PATCH] Added first rp2040 code example --- .gitignore | 2 ++ rp2040/.cargo/config | 42 ++++++++++++++++++++++++ rp2040/Cargo.toml | 45 ++++++++++++++++++++++++++ rp2040/memory.x | 15 +++++++++ rp2040/pico-load | 12 +++++++ rp2040/src/main.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 192 insertions(+) create mode 100644 rp2040/.cargo/config create mode 100644 rp2040/Cargo.toml create mode 100644 rp2040/memory.x create mode 100755 rp2040/pico-load create mode 100644 rp2040/src/main.rs diff --git a/.gitignore b/.gitignore index 43f998b..30a8261 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ firmware/compile_commands.json firmware/.cache/clangd/index firmware/.ccls-cache +rp2040/target +rp2040/Cargo.lock diff --git a/rp2040/.cargo/config b/rp2040/.cargo/config new file mode 100644 index 0000000..ed10a10 --- /dev/null +++ b/rp2040/.cargo/config @@ -0,0 +1,42 @@ +# +# Cargo Configuration for the https://github.com/rp-rs/rp-hal.git repository. +# +# Copyright (c) The RP-RS Developers, 2021 +# +# You might want to make a similar file in your own repository if you are +# writing programs for Raspberry Silicon microcontrollers. +# +# This file is MIT or Apache-2.0 as per the repository README.md file +# + +[build] +# Set the default target to match the Cortex-M0+ in the RP2040 +target = "thumbv6m-none-eabi" + +# Target specific options +[target.thumbv6m-none-eabi] +# Pass some extra options to rustc, some of which get passed on to the linker. +# +# * linker argument --nmagic turns off page alignment of sections (which saves +# flash space) +# * linker argument -Tlink.x tells the linker to use link.x as the linker +# script. This is usually provided by the cortex-m-rt crate, and by default +# the version in that crate will include a file called `memory.x` which +# describes the particular memory layout for your specific chip. +# * inline-threshold=5 makes the compiler more aggressive and inlining functions +# * no-vectorize-loops turns off the loop vectorizer (seeing as the M0+ doesn't +# have SIMD) +rustflags = [ + "-C", "link-arg=--nmagic", + "-C", "link-arg=-Tlink.x", + "-C", "inline-threshold=5", + "-C", "no-vectorize-loops", +] + +# This runner will make a UF2 file and then copy it to a mounted RP2040 in USB +# Bootloader mode: +runner = "elf2uf2-rs -d" + +# This runner will find a supported SWD debug probe and flash your RP2040 over +# SWD: +# runner = "probe-run --chip RP2040" diff --git a/rp2040/Cargo.toml b/rp2040/Cargo.toml new file mode 100644 index 0000000..e4205ec --- /dev/null +++ b/rp2040/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "rp2040" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m = "0.7.2" +waveshare-rp2040-zero = "0.6.0" +rp2040-boot2 = { version = "0.2.0", optional = true } +rp2040-hal = { version = "0.8.0" } +cortex-m-rt = { version = "0.7", optional = true } +panic-halt= "0.2.0" +embedded-hal ="0.2.5" +fugit = "0.3.5" +nb = "1.0.0" +smart-leds = "0.3.0" +ws2812-pio = "0.6.0" + +[features] +# This is the set of features we enable by default +default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] + +# critical section that is safe for multicore use +critical-section-impl = ["rp2040-hal/critical-section-impl"] + +# 2nd stage bootloaders for rp2040 +boot2 = ["rp2040-boot2"] + +# Minimal startup / runtime for Cortex-M microcontrollers +rt = ["cortex-m-rt","rp2040-hal/rt"] + +# This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. +# Only required for RP2040 B0 and RP2040 B1, but it doesn't hurt to enable it +rp2040-e5 = ["rp2040-hal/rp2040-e5"] + +# Memoize(cache) ROM function pointers on first use to improve performance +rom-func-cache = ["rp2040-hal/rom-func-cache"] + +# Disable automatic mapping of language features (like floating point math) to ROM functions +disable-intrinsics = ["rp2040-hal/disable-intrinsics"] + +# This enables ROM functions for f64 math that were not present in the earliest RP2040s +rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] diff --git a/rp2040/memory.x b/rp2040/memory.x new file mode 100644 index 0000000..4077aab --- /dev/null +++ b/rp2040/memory.x @@ -0,0 +1,15 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} + +EXTERN(BOOT2_FIRMWARE) + +SECTIONS { + /* ### Boot loader */ + .boot2 ORIGIN(BOOT2) : + { + KEEP(*(.boot2)); + } > BOOT2 +} INSERT BEFORE .text; diff --git a/rp2040/pico-load b/rp2040/pico-load new file mode 100755 index 0000000..2a31890 --- /dev/null +++ b/rp2040/pico-load @@ -0,0 +1,12 @@ +#!/bin/bash +sudo umount /mnt/usb +while [ ! -f /mnt/usb/INFO_UF2.TXT ]; do + sudo mount /dev/sda1 /mnt/usb -o umask=000 + sleep 1 +done +set -e +# cargo build --release --example waveshare_rp2040_zero_neopixel_rainbow +cargo run --release +# elf2uf2-rs $1 +# cp $1.uf2 /mnt/usb +sudo umount /mnt/usb diff --git a/rp2040/src/main.rs b/rp2040/src/main.rs new file mode 100644 index 0000000..b505f00 --- /dev/null +++ b/rp2040/src/main.rs @@ -0,0 +1,76 @@ +//! Rainbow effect color wheel using the onboard NeoPixel on an Waveshare RP2040 Zero board +//! +//! This flows smoothly through various colors on the onboard NeoPixel. +//! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the +//! RP2040's PIO block. +#![no_std] +#![no_main] + +use embedded_hal::timer::CountDown; +use fugit::ExtU32; +use panic_halt as _; +use smart_leds::{SmartLedsWrite, RGB8}; +use waveshare_rp2040_zero::entry; +use waveshare_rp2040_zero::{ + hal::{ + clocks::{init_clocks_and_plls, Clock}, + pac, + pio::PIOExt, + timer::Timer, + watchdog::Watchdog, + Sio, + }, + Pins, XOSC_CRYSTAL_FREQ, +}; +use ws2812_pio::Ws2812; + +#[entry] +fn main() -> ! { + let mut pac = pac::Peripherals::take().unwrap(); + + let mut watchdog = Watchdog::new(pac.WATCHDOG); + + let clocks = init_clocks_and_plls( + XOSC_CRYSTAL_FREQ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + let sio = Sio::new(pac.SIO); + let pins = Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + let timer = Timer::new(pac.TIMER, &mut pac.RESETS); + let mut delay = timer.count_down(); + + // Configure the addressable LED + let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); + let mut ws = Ws2812::new( + // The onboard NeoPixel is attached to GPIO pin #16 on the Feather RP2040. + pins.neopixel.into_mode(), + &mut pio, + sm0, + clocks.peripheral_clock.freq(), + timer.count_down(), + ); + + // Infinite colour wheel loop + loop { + let color_green : RGB8 = (0, 10, 10).into(); + ws.write([color_green].iter().copied()).unwrap(); + + delay.start(25.millis()); + let _ = nb::block!(delay.wait()); + } +} +