Skip to content

Commit ce80657

Browse files
authored
add seeeduino_xiao_rp2040_neopixel_rainbow example (#94)
1 parent eaa0b90 commit ce80657

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

boards/seeeduino-xiao-rp2040/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ embedded-hal.workspace = true
2121
fugit.workspace = true
2222
nb.workspace = true
2323
panic-halt.workspace = true
24+
smart-leds.workspace = true
25+
ws2812-pio.workspace = true
2426

2527
[features]
2628
# This is the set of features we enable by default
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//! Rainbow effect color wheel using the onboard NeoPixel on a Seeed XIAO RP2040 board
2+
//!
3+
//! This flows smoothly through various colours on the onboard NeoPixel.
4+
//! Uses the `ws2812_pio` driver to control the NeoPixel, which in turns uses the
5+
//! RP2040's PIO block.
6+
#![no_std]
7+
#![no_main]
8+
9+
use core::iter::once;
10+
use embedded_hal::delay::DelayNs;
11+
use panic_halt as _;
12+
use smart_leds::{brightness, SmartLedsWrite, RGB8};
13+
14+
use seeeduino_xiao_rp2040::{
15+
entry,
16+
hal::{
17+
clocks::{init_clocks_and_plls, Clock},
18+
gpio::PinState,
19+
pac,
20+
pio::PIOExt,
21+
timer::Timer,
22+
watchdog::Watchdog,
23+
Sio,
24+
},
25+
Pins, XOSC_CRYSTAL_FREQ,
26+
};
27+
28+
use ws2812_pio::Ws2812;
29+
30+
/// Entry point to our bare-metal application.
31+
///
32+
/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function
33+
/// as soon as all global variables are initialised.
34+
///
35+
/// The function configures the RP2040 peripherals, then infinitely cycles the built-in LED colour from red, to green,
36+
/// to blue and back to red.
37+
#[entry]
38+
fn main() -> ! {
39+
let mut pac = pac::Peripherals::take().unwrap();
40+
41+
let mut watchdog = Watchdog::new(pac.WATCHDOG);
42+
43+
let clocks = init_clocks_and_plls(
44+
XOSC_CRYSTAL_FREQ,
45+
pac.XOSC,
46+
pac.CLOCKS,
47+
pac.PLL_SYS,
48+
pac.PLL_USB,
49+
&mut pac.RESETS,
50+
&mut watchdog,
51+
)
52+
.ok()
53+
.unwrap();
54+
55+
let sio = Sio::new(pac.SIO);
56+
let pins = Pins::new(
57+
pac.IO_BANK0,
58+
pac.PADS_BANK0,
59+
sio.gpio_bank0,
60+
&mut pac.RESETS,
61+
);
62+
63+
let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);
64+
65+
// Turn on neopixel power
66+
pins.neopixel_power
67+
.into_push_pull_output_in_state(PinState::High);
68+
69+
// Configure the addressable LED
70+
let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS);
71+
let mut ws = Ws2812::new(
72+
// The onboard NeoPixel is attached to GPIO pin #16 on the Waveshare RP2040-Zero.
73+
pins.neopixel_data.into_function(),
74+
&mut pio,
75+
sm0,
76+
clocks.peripheral_clock.freq(),
77+
timer.count_down(),
78+
);
79+
80+
// Infinite colour wheel loop
81+
let mut n: u8 = 128;
82+
let mut timer = timer; // rebind to force a copy of the timer
83+
loop {
84+
ws.write(brightness(once(wheel(n)), 32)).unwrap();
85+
n = n.wrapping_add(1);
86+
87+
timer.delay_ms(25);
88+
}
89+
}
90+
91+
/// Convert a number from `0..=255` to an RGB color triplet.
92+
///
93+
/// The colours are a transition from red, to green, to blue and back to red.
94+
fn wheel(mut wheel_pos: u8) -> RGB8 {
95+
wheel_pos = 255 - wheel_pos;
96+
if wheel_pos < 85 {
97+
// No green in this sector - red and blue only
98+
(255 - (wheel_pos * 3), 0, wheel_pos * 3).into()
99+
} else if wheel_pos < 170 {
100+
// No red in this sector - green and blue only
101+
wheel_pos -= 85;
102+
(0, wheel_pos * 3, 255 - (wheel_pos * 3)).into()
103+
} else {
104+
// No blue in this sector - red and green only
105+
wheel_pos -= 170;
106+
(wheel_pos * 3, 255 - (wheel_pos * 3), 0).into()
107+
}
108+
}

0 commit comments

Comments
 (0)