Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add seeeduino_xiao_rp2040_neopixel_rainbow example #94

Merged
merged 1 commit into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions boards/seeeduino-xiao-rp2040/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
Loading