From 63dd0b3066b9d56c1f3de34515f78fe02af7f6d9 Mon Sep 17 00:00:00 2001
From: Wilfried Chauveau <wilfried.chauveau@ithinuel.me>
Date: Thu, 16 Sep 2021 07:16:20 +0100
Subject: [PATCH] add Pro Micro rainbow example (uses PIO & Timer's Countdown)

---
 Cargo.toml                                    |  1 +
 boards/pro_micro_rp2040/Cargo.toml            | 29 +++++++
 .../examples/pro_micro_rainbow.rs             | 87 +++++++++++++++++++
 boards/pro_micro_rp2040/src/lib.rs            | 34 ++++++++
 4 files changed, 151 insertions(+)
 create mode 100644 boards/pro_micro_rp2040/Cargo.toml
 create mode 100644 boards/pro_micro_rp2040/examples/pro_micro_rainbow.rs
 create mode 100644 boards/pro_micro_rp2040/src/lib.rs

diff --git a/Cargo.toml b/Cargo.toml
index d89057d..f7adced 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,5 @@ members = [
     "boards/pico_explorer",
     "boards/pico_lipo_16mb",
     "boards/adafruit_macropad",
+    "boards/pro_micro_rp2040",
 ]
diff --git a/boards/pro_micro_rp2040/Cargo.toml b/boards/pro_micro_rp2040/Cargo.toml
new file mode 100644
index 0000000..9e9a002
--- /dev/null
+++ b/boards/pro_micro_rp2040/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "pro_micro_rp2040"
+version = "0.1.0"
+authors = ["Wilfried Chauveau <wilfried.chauveau@ithinuel.me>"]
+edition = "2018"
+homepage = "https://github.com/rp-rs/rp-hal/boards/pro_micro_rp2040"
+description = "Board Support Package for the Sparkfun Pro Micro RP2040"
+license = "MIT OR Apache-2.0"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+cortex-m = "0.7.2"
+rp2040-hal = { path = "../../rp2040-hal", version = "0.2.0" }
+cortex-m-rt = { version = "0.7.0", optional = true }
+embedded-hal = { version = "0.2.4", features = ["unproven"] }
+
+[features]
+default = ["rt"]
+rt = ["cortex-m-rt", "rp2040-hal/rt"]
+
+[dev-dependencies]
+panic-halt = "0.2.0"
+rp2040-boot2 = { git = "https://github.com/rp-rs/rp2040-boot2-rs", rev = "67400f600b192e950b58df79ddc9b57ff209ef08" }
+smart-leds = "0.3.0"
+embedded-time = "0.12.0"
+nb = "1.0.0"
+pio = { git = "https://github.com/rp-rs/pio-rs.git", branch = "main" }
+ws2812-pio = { git = "https://github.com/ithinuel/ws2812-pio-rs" }
diff --git a/boards/pro_micro_rp2040/examples/pro_micro_rainbow.rs b/boards/pro_micro_rp2040/examples/pro_micro_rainbow.rs
new file mode 100644
index 0000000..2af9c7b
--- /dev/null
+++ b/boards/pro_micro_rp2040/examples/pro_micro_rainbow.rs
@@ -0,0 +1,87 @@
+//! Cycles colors on on the on board addressable LED.
+#![no_std]
+#![no_main]
+
+use core::iter::once;
+use cortex_m_rt::entry;
+use embedded_hal::timer::CountDown;
+use embedded_time::duration::Extensions;
+use panic_halt as _;
+
+use pro_micro_rp2040::{
+    hal::{
+        clocks::{init_clocks_and_plls, Clock},
+        gpio::{FunctionPio0, Pin},
+        pac,
+        sio::Sio,
+        timer::Timer,
+        watchdog::Watchdog,
+    },
+    XOSC_CRYSTAL_FREQ,
+};
+use smart_leds::{brightness, SmartLedsWrite, RGB8};
+use ws2812_pio::Ws2812;
+
+#[link_section = ".boot2"]
+#[used]
+pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER;
+
+#[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 = pro_micro_rp2040::Pins::new(
+        pac.IO_BANK0,
+        pac.PADS_BANK0,
+        sio.gpio_bank0,
+        &mut pac.RESETS,
+    );
+    let _led: Pin<_, FunctionPio0> = pins.led.into_mode();
+    let timer = Timer::new(pac.TIMER);
+    let mut delay = timer.count_down();
+
+    let mut ws = Ws2812::new(
+        25,
+        pac.PIO0,
+        &mut pac.RESETS,
+        clocks.system_clock.freq(),
+        timer.count_down(),
+    );
+
+    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());
+    }
+}
+/// Input a value 0 to 255 to get a color value
+/// The colours are a transition r - g - b - back to r.
+fn wheel(mut wheel_pos: u8) -> RGB8 {
+    wheel_pos = 255 - wheel_pos;
+    if wheel_pos < 85 {
+        return (255 - wheel_pos * 3, 0, wheel_pos * 3).into();
+    }
+    if wheel_pos < 170 {
+        wheel_pos -= 85;
+        return (0, wheel_pos * 3, 255 - wheel_pos * 3).into();
+    }
+    wheel_pos -= 170;
+    (wheel_pos * 3, 255 - wheel_pos * 3, 0).into()
+}
diff --git a/boards/pro_micro_rp2040/src/lib.rs b/boards/pro_micro_rp2040/src/lib.rs
new file mode 100644
index 0000000..e7dd0db
--- /dev/null
+++ b/boards/pro_micro_rp2040/src/lib.rs
@@ -0,0 +1,34 @@
+#![no_std]
+
+pub use rp2040_hal as hal;
+#[cfg(feature = "rt")]
+extern crate cortex_m_rt;
+#[cfg(feature = "rt")]
+pub use cortex_m_rt::entry;
+
+pub use hal::pac;
+
+hal::bsp_pins!(
+    Gpio0 { name: tx0 },
+    Gpio1 { name: rx0 },
+    Gpio2 { name: gpio2 },
+    Gpio3 { name: gpio3 },
+    Gpio4 { name: gpio4 },
+    Gpio5 { name: gpio5 },
+    Gpio6 { name: gpio6 },
+    Gpio7 { name: gpio7 },
+    Gpio8 { name: tx1 },
+    Gpio9 { name: rx1 },
+    Gpio16 { name: sda },
+    Gpio17 { name: scl },
+    Gpio20 { name: cipo },
+    Gpio21 { name: ncs },
+    Gpio22 { name: sck },
+    Gpio25 { name: led },
+    Gpio26 { name: adc0 },
+    Gpio27 { name: adc1 },
+    Gpio28 { name: adc2 },
+    Gpio29 { name: adc3 },
+);
+
+pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000;