Fill in remaining color settings
This commit is contained in:
parent
3e1245260d
commit
3cc0d6aaad
2 changed files with 149 additions and 30 deletions
|
|
@ -37,6 +37,17 @@ impl HappyEyes {
|
||||||
image_data: Bmp::from_slice(include_bytes!("assets/eye1.bmp")).unwrap(),
|
image_data: Bmp::from_slice(include_bytes!("assets/eye1.bmp")).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_colored<D: DrawTarget<Color = Rgb888>>(
|
||||||
|
&self,
|
||||||
|
target: &mut D,
|
||||||
|
color: Rgb888,
|
||||||
|
) -> Result<(), D::Error> {
|
||||||
|
self.draw(&mut ColorMapFilter {
|
||||||
|
inner_target: target,
|
||||||
|
filter: |c| mix(c, color),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drawable for HappyEyes {
|
impl Drawable for HappyEyes {
|
||||||
|
|
@ -122,12 +133,19 @@ impl<'a, D: Dimensions> Dimensions for RainbowFilter<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ColorMapFilter<'a, D> {
|
pub struct ColorMapFilter<'a, D, F>
|
||||||
|
where
|
||||||
|
F: FnMut(Rgb888) -> Rgb888,
|
||||||
|
{
|
||||||
pub inner_target: &'a mut D,
|
pub inner_target: &'a mut D,
|
||||||
pub filter: fn(Rgb888) -> Rgb888,
|
pub filter: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D: DrawTarget<Color = Rgb888>> DrawTarget for ColorMapFilter<'a, D> {
|
impl<'a, D, F> DrawTarget for ColorMapFilter<'a, D, F>
|
||||||
|
where
|
||||||
|
D: DrawTarget<Color = Rgb888>,
|
||||||
|
F: FnMut(Rgb888) -> Rgb888,
|
||||||
|
{
|
||||||
type Color = D::Color;
|
type Color = D::Color;
|
||||||
type Error = D::Error;
|
type Error = D::Error;
|
||||||
|
|
||||||
|
|
@ -143,7 +161,10 @@ impl<'a, D: DrawTarget<Color = Rgb888>> DrawTarget for ColorMapFilter<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D: Dimensions> Dimensions for ColorMapFilter<'a, D> {
|
impl<'a, D: Dimensions, F> Dimensions for ColorMapFilter<'a, D, F>
|
||||||
|
where
|
||||||
|
F: FnMut(Rgb888) -> Rgb888,
|
||||||
|
{
|
||||||
fn bounding_box(&self) -> Rectangle {
|
fn bounding_box(&self) -> Rectangle {
|
||||||
self.inner_target.bounding_box()
|
self.inner_target.bounding_box()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,17 @@ use embassy_rp::pio_programs::ws2812::{PioWs2812, PioWs2812Program};
|
||||||
use embassy_rp::pwm::{self, Pwm};
|
use embassy_rp::pwm::{self, Pwm};
|
||||||
use embassy_rp::rom_data::reset_to_usb_boot;
|
use embassy_rp::rom_data::reset_to_usb_boot;
|
||||||
use embassy_rp::spi::{self, Blocking, Spi};
|
use embassy_rp::spi::{self, Blocking, Spi};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_rp::spinlock_mutex::SpinlockRawMutex;
|
||||||
use embassy_sync::signal::Signal;
|
use embassy_sync::signal::Signal;
|
||||||
use embassy_time::{Delay, Duration, Instant, Ticker, Timer};
|
use embassy_time::{Delay, Duration, Instant, Ticker, Timer};
|
||||||
use embedded_graphics::pixelcolor::Rgb888;
|
use embedded_graphics::pixelcolor::Rgb888;
|
||||||
use embedded_graphics::prelude::{DrawTarget, Drawable, RgbColor, Size};
|
use embedded_graphics::prelude::{DrawTarget, Drawable, RgbColor, Size, WebColors};
|
||||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
use embedded_hal_bus::spi::ExclusiveDevice;
|
||||||
use mipidsi::interface::SpiInterface;
|
use mipidsi::interface::SpiInterface;
|
||||||
use mipidsi::models::ST7789;
|
use mipidsi::models::ST7789;
|
||||||
use mipidsi::options::Orientation;
|
use mipidsi::options::Orientation;
|
||||||
|
|
||||||
use crate::art::{Hal, HappyEyes, Rainbow, RainbowFilter};
|
use crate::art::{ColorMapFilter, Hal, HappyEyes, Rainbow, RainbowFilter};
|
||||||
use crate::led_matrix::{LedMatrix, Serpentine};
|
use crate::led_matrix::{LedMatrix, Serpentine};
|
||||||
|
|
||||||
use defmt_rtt as _;
|
use defmt_rtt as _;
|
||||||
|
|
@ -164,13 +164,62 @@ impl ButtonStates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LedConfig {
|
#[derive(Clone, Copy, Default)]
|
||||||
|
struct LedConfig {
|
||||||
|
pattern: LedPattern,
|
||||||
|
hal: HalConfig,
|
||||||
|
happy: HappyConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Default)]
|
||||||
|
enum LedPattern {
|
||||||
|
#[default]
|
||||||
Blank,
|
Blank,
|
||||||
Hal,
|
Hal,
|
||||||
Happy,
|
Happy,
|
||||||
}
|
}
|
||||||
|
|
||||||
static LED_CONFIG_SIGNAL: Signal<CriticalSectionRawMutex, LedConfig> = Signal::new();
|
#[derive(Clone, Copy, PartialEq, Default)]
|
||||||
|
enum HalConfig {
|
||||||
|
#[default]
|
||||||
|
Red,
|
||||||
|
Blue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HalConfig {
|
||||||
|
fn next(self) -> Self {
|
||||||
|
match self {
|
||||||
|
HalConfig::Red => HalConfig::Blue,
|
||||||
|
HalConfig::Blue => HalConfig::Red,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Default)]
|
||||||
|
enum HappyConfig {
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
#[default]
|
||||||
|
Purple,
|
||||||
|
Pink,
|
||||||
|
RainbowSlow,
|
||||||
|
RainbowFast,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HappyConfig {
|
||||||
|
fn next(self) -> Self {
|
||||||
|
match self {
|
||||||
|
HappyConfig::Green => HappyConfig::Blue,
|
||||||
|
HappyConfig::Blue => HappyConfig::Purple,
|
||||||
|
HappyConfig::Purple => HappyConfig::Pink,
|
||||||
|
HappyConfig::Pink => HappyConfig::RainbowSlow,
|
||||||
|
HappyConfig::RainbowSlow => HappyConfig::RainbowFast,
|
||||||
|
HappyConfig::RainbowFast => HappyConfig::Green,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LED_CONFIG_SIGNAL: Signal<SpinlockRawMutex<0>, LedConfig> = Signal::new();
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn controller_task(buttons: Buttons) {
|
async fn controller_task(buttons: Buttons) {
|
||||||
|
|
@ -179,6 +228,8 @@ async fn controller_task(buttons: Buttons) {
|
||||||
let mut stable_chord = 0;
|
let mut stable_chord = 0;
|
||||||
let mut pending_chord = 0;
|
let mut pending_chord = 0;
|
||||||
|
|
||||||
|
let mut led_config = LedConfig::default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let state = buttons.read();
|
let state = buttons.read();
|
||||||
let new_chord = state.chord();
|
let new_chord = state.chord();
|
||||||
|
|
@ -204,18 +255,29 @@ async fn controller_task(buttons: Buttons) {
|
||||||
match stable_chord {
|
match stable_chord {
|
||||||
0x1 => {
|
0x1 => {
|
||||||
// blank display
|
// blank display
|
||||||
LED_CONFIG_SIGNAL.signal(LedConfig::Blank);
|
led_config.pattern = LedPattern::Blank;
|
||||||
|
LED_CONFIG_SIGNAL.signal(led_config);
|
||||||
}
|
}
|
||||||
0x2 => {
|
0x2 => {
|
||||||
// happy
|
// happy
|
||||||
LED_CONFIG_SIGNAL.signal(LedConfig::Happy);
|
if led_config.pattern == LedPattern::Happy {
|
||||||
|
led_config.happy = led_config.happy.next();
|
||||||
|
} else {
|
||||||
|
led_config.pattern = LedPattern::Happy;
|
||||||
|
}
|
||||||
|
LED_CONFIG_SIGNAL.signal(led_config);
|
||||||
}
|
}
|
||||||
0x4 => {
|
0x4 => {
|
||||||
// hal
|
// hal
|
||||||
LED_CONFIG_SIGNAL.signal(LedConfig::Hal);
|
if led_config.pattern == LedPattern::Hal {
|
||||||
|
led_config.hal = led_config.hal.next();
|
||||||
|
} else {
|
||||||
|
led_config.pattern = LedPattern::Hal;
|
||||||
|
}
|
||||||
|
LED_CONFIG_SIGNAL.signal(led_config);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// unknown pattern
|
// unknown chord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,9 +292,12 @@ async fn controller_task(buttons: Buttons) {
|
||||||
async fn led_task(mut led_surface: LedMatrix<'static>) {
|
async fn led_task(mut led_surface: LedMatrix<'static>) {
|
||||||
let hal = Hal::new();
|
let hal = Hal::new();
|
||||||
let eyes = HappyEyes::new();
|
let eyes = HappyEyes::new();
|
||||||
let mut rainbow = Rainbow {
|
let mut rainbow_slow = Rainbow {
|
||||||
// rate: Duration::from_secs(10),
|
rate: Duration::from_secs(10),
|
||||||
// width: 300,
|
width: 300,
|
||||||
|
elapsed: Duration::from_secs(0),
|
||||||
|
};
|
||||||
|
let mut rainbow_fast = Rainbow {
|
||||||
rate: Duration::from_secs(1),
|
rate: Duration::from_secs(1),
|
||||||
width: 80,
|
width: 80,
|
||||||
elapsed: Duration::from_secs(0),
|
elapsed: Duration::from_secs(0),
|
||||||
|
|
@ -241,29 +306,62 @@ async fn led_task(mut led_surface: LedMatrix<'static>) {
|
||||||
let mut ticker = Ticker::every(Duration::from_hz(30));
|
let mut ticker = Ticker::every(Duration::from_hz(30));
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let mut led_config = LedConfig::Blank;
|
let mut led_config = LedConfig::default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let elapsed = start.elapsed();
|
let elapsed = start.elapsed();
|
||||||
rainbow.elapsed = elapsed;
|
rainbow_slow.elapsed = elapsed;
|
||||||
|
rainbow_fast.elapsed = elapsed;
|
||||||
|
|
||||||
if let Some(new_config) = LED_CONFIG_SIGNAL.try_take() {
|
if let Some(new_config) = LED_CONFIG_SIGNAL.try_take() {
|
||||||
led_config = new_config;
|
led_config = new_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
led_surface.clear(Rgb888::BLACK).ok();
|
led_surface.clear(Rgb888::BLACK).ok();
|
||||||
match led_config {
|
match led_config.pattern {
|
||||||
LedConfig::Blank => {}
|
LedPattern::Blank => {}
|
||||||
LedConfig::Hal => {
|
LedPattern::Hal => match led_config.hal {
|
||||||
|
HalConfig::Red => {
|
||||||
hal.draw(&mut led_surface).ok();
|
hal.draw(&mut led_surface).ok();
|
||||||
}
|
}
|
||||||
LedConfig::Happy => {
|
HalConfig::Blue => {
|
||||||
eyes.draw(&mut RainbowFilter {
|
hal.draw(&mut ColorMapFilter {
|
||||||
inner_target: &mut led_surface,
|
inner_target: &mut led_surface,
|
||||||
rainbow: &rainbow,
|
filter: |color| Rgb888::new(color.b(), color.g(), color.r() / 2),
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
LedPattern::Happy => match led_config.happy {
|
||||||
|
HappyConfig::Green => {
|
||||||
|
eyes.draw_colored(&mut led_surface, Rgb888::GREEN).ok();
|
||||||
|
}
|
||||||
|
HappyConfig::Blue => {
|
||||||
|
eyes.draw_colored(&mut led_surface, Rgb888::BLUE).ok();
|
||||||
|
}
|
||||||
|
HappyConfig::Purple => {
|
||||||
|
eyes.draw_colored(&mut led_surface, Rgb888::new(172, 20, 172))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
HappyConfig::Pink => {
|
||||||
|
eyes.draw_colored(&mut led_surface, Rgb888::CSS_HOT_PINK)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
HappyConfig::RainbowSlow => {
|
||||||
|
eyes.draw(&mut RainbowFilter {
|
||||||
|
inner_target: &mut led_surface,
|
||||||
|
rainbow: &rainbow_slow,
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
HappyConfig::RainbowFast => {
|
||||||
|
eyes.draw(&mut RainbowFilter {
|
||||||
|
inner_target: &mut led_surface,
|
||||||
|
rainbow: &rainbow_fast,
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
led_surface.sync().await;
|
led_surface.sync().await;
|
||||||
ticker.next().await;
|
ticker.next().await;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue