diff --git a/boards/feather_rp2040/Cargo.toml b/boards/feather_rp2040/Cargo.toml index 87fed6f..10313a0 100644 --- a/boards/feather_rp2040/Cargo.toml +++ b/boards/feather_rp2040/Cargo.toml @@ -19,7 +19,11 @@ embedded-time = "0.12.0" panic-halt= "0.2.0" embedded-hal ="0.2.5" rp2040-boot2 = { git = "https://github.com/rp-rs/rp2040-boot2-rs", rev = "d2128ef9875e91e454dd0fb0d747c7439ae0627b" } +nb = "1.0.0" +smart-leds = "0.3.0" +pio = { git = "https://github.com/rp-rs/pio-rs.git", branch = "main" } +ws2812-pio = { git = "https://github.com/ithinuel/ws2812-pio-rs" } [features] default = ["rt"] -rt = ["cortex-m-rt","rp2040-hal/rt"] \ No newline at end of file +rt = ["cortex-m-rt","rp2040-hal/rt"] diff --git a/boards/feather_rp2040/README.md b/boards/feather_rp2040/README.md index 76f9173..8dd6bdf 100644 --- a/boards/feather_rp2040/README.md +++ b/boards/feather_rp2040/README.md @@ -55,12 +55,16 @@ $ cargo install elf2uf2-rs, then repeating the `cargo run` command above. ### [feather_blinky](./examples/feather_blinky.rs) -Flashes the Feather's on-board LED on and off. +Flashes the Feather's onboard LED on and off. + +### [feather_neopixel_rainbow](./examples/feather_neopixel_rainbow.rs) + +Flows smoothly through various colors on the Feather's onboard NeoPixel LED. ## Contributing Contributions are what make the open source community such an amazing place to -be learn, inspire, and create. Any contributions you make are **greatly +be, learn, inspire, and create. Any contributions you make are **greatly appreciated**. The steps are: diff --git a/boards/feather_rp2040/examples/feather_neopixel_rainbow.rs b/boards/feather_rp2040/examples/feather_neopixel_rainbow.rs new file mode 100644 index 0000000..b0bd002 --- /dev/null +++ b/boards/feather_rp2040/examples/feather_neopixel_rainbow.rs @@ -0,0 +1,100 @@ +//! Rainbow effect color wheel using the onboard NeoPixel on an Adafruit Feather RP2040 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 core::iter::once; +use cortex_m_rt::entry; +use embedded_hal::timer::CountDown; +use embedded_time::duration::Extensions; +use feather_rp2040::{ + hal::{ + clocks::{init_clocks_and_plls, Clock}, + gpio::{FunctionPio0, Pin}, + pac, + sio::Sio, + timer::Timer, + watchdog::Watchdog, + }, + Pins, XOSC_CRYSTAL_FREQ, +}; +use panic_halt as _; +use smart_leds::{brightness, SmartLedsWrite, RGB8}; +use ws2812_pio::Ws2812; +#[link_section = ".boot2"] +#[used] +pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GD25Q64CS; + +#[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 _neopixel: Pin<_, FunctionPio0> = pins.neopixel.into_mode(); + + let timer = Timer::new(pac.TIMER); + let mut delay = timer.count_down(); + + // Configure the addressable LED + let mut ws = Ws2812::new( + // The onboard NeoPixel is attached to GPIO pin #16 on the Feather RP2040. + 16, + pac.PIO0, + &mut pac.RESETS, + clocks.peripheral_clock.freq(), + timer.count_down(), + ); + + // Infinite colour wheel loop + let mut n: u8 = 128; + loop { + ws.write(brightness(once(wheel(n)), 32)).unwrap(); + n = n.wrapping_add(1); + + delay.start(25.milliseconds()); + let _ = nb::block!(delay.wait()); + } +} + +/// 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() + } +}