From ce80657b91eef4edcf3efc776b5ae8c0705ceb32 Mon Sep 17 00:00:00 2001 From: Andrew Straw Date: Thu, 2 Jan 2025 00:31:03 +0100 Subject: [PATCH] add seeeduino_xiao_rp2040_neopixel_rainbow example (#94) --- boards/seeeduino-xiao-rp2040/Cargo.toml | 2 + .../seeeduino_xiao_rp2040_neopixel_rainbow.rs | 108 ++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_neopixel_rainbow.rs diff --git a/boards/seeeduino-xiao-rp2040/Cargo.toml b/boards/seeeduino-xiao-rp2040/Cargo.toml index 5a66e60..9289e9a 100644 --- a/boards/seeeduino-xiao-rp2040/Cargo.toml +++ b/boards/seeeduino-xiao-rp2040/Cargo.toml @@ -21,6 +21,8 @@ embedded-hal.workspace = true fugit.workspace = true nb.workspace = true panic-halt.workspace = true +smart-leds.workspace = true +ws2812-pio.workspace = true [features] # This is the set of features we enable by default diff --git a/boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_neopixel_rainbow.rs b/boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_neopixel_rainbow.rs new file mode 100644 index 0000000..a533004 --- /dev/null +++ b/boards/seeeduino-xiao-rp2040/examples/seeeduino_xiao_rp2040_neopixel_rainbow.rs @@ -0,0 +1,108 @@ +//! Rainbow effect color wheel using the onboard NeoPixel on a Seeed XIAO RP2040 board +//! +//! This flows smoothly through various colours 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 core::iter::once; +use embedded_hal::delay::DelayNs; +use panic_halt as _; +use smart_leds::{brightness, SmartLedsWrite, RGB8}; + +use seeeduino_xiao_rp2040::{ + entry, + hal::{ + clocks::{init_clocks_and_plls, Clock}, + gpio::PinState, + pac, + pio::PIOExt, + timer::Timer, + watchdog::Watchdog, + Sio, + }, + Pins, XOSC_CRYSTAL_FREQ, +}; + +use ws2812_pio::Ws2812; + +/// Entry point to our bare-metal application. +/// +/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function +/// as soon as all global variables are initialised. +/// +/// The function configures the RP2040 peripherals, then infinitely cycles the built-in LED colour from red, to green, +/// to blue and back to red. +#[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, &clocks); + + // Turn on neopixel power + pins.neopixel_power + .into_push_pull_output_in_state(PinState::High); + + // 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 Waveshare RP2040-Zero. + pins.neopixel_data.into_function(), + &mut pio, + sm0, + clocks.peripheral_clock.freq(), + timer.count_down(), + ); + + // Infinite colour wheel loop + let mut n: u8 = 128; + let mut timer = timer; // rebind to force a copy of the timer + loop { + ws.write(brightness(once(wheel(n)), 32)).unwrap(); + n = n.wrapping_add(1); + + timer.delay_ms(25); + } +} + +/// Convert a number from `0..=255` to an RGB color triplet. +/// +/// The colours are a transition from red, to green, to blue and back to red. +fn wheel(mut wheel_pos: u8) -> RGB8 { + wheel_pos = 255 - wheel_pos; + if wheel_pos < 85 { + // No green in this sector - red and blue only + (255 - (wheel_pos * 3), 0, wheel_pos * 3).into() + } else if wheel_pos < 170 { + // No red in this sector - green and blue only + wheel_pos -= 85; + (0, wheel_pos * 3, 255 - (wheel_pos * 3)).into() + } else { + // No blue in this sector - red and green only + wheel_pos -= 170; + (wheel_pos * 3, 255 - (wheel_pos * 3), 0).into() + } +}