From 4d02d0825a2091eca1263d8e21a75aed09696b4a Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Sat, 18 Mar 2023 00:58:42 +0100 Subject: [PATCH] Split firmware inte left.rs and right.rs. --- Cargo.lock | 60 ++++++------ Cargo.toml | 4 +- build.rs | 17 ++-- layers.ron => layers-left.ron | 28 ------ layers-right.ron | 31 +++++++ run | 2 +- src/allocator.rs | 2 +- src/bin/layers-left.pc | Bin 0 -> 37 bytes src/bin/layers-right.pc | Bin 0 -> 37 bytes src/bin/left.rs | 88 ++++++++++++++++++ src/bin/right.rs | 89 ++++++++++++++++++ src/board.rs | 72 ++++++++++++++- src/keyboard.rs | 44 ++++++++- src/lib.rs | 13 +++ src/main.rs | 166 ---------------------------------- src/usb.rs | 16 ++++ src/usb/keyboard.rs | 2 +- src/usb/keyboard/report.rs | 3 +- src/util.rs | 24 +++++ 19 files changed, 416 insertions(+), 245 deletions(-) rename layers.ron => layers-left.ron (52%) create mode 100644 layers-right.ron create mode 100644 src/bin/layers-left.pc create mode 100644 src/bin/layers-right.pc create mode 100644 src/bin/left.rs create mode 100644 src/bin/right.rs create mode 100644 src/lib.rs delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 4854f90..56e7df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -670,36 +670,6 @@ dependencies = [ "either", ] -[[package]] -name = "itsybitsy_rp2040_keyboard" -version = "0.1.0" -dependencies = [ - "cortex-m", - "cortex-m-rt", - "embassy-executor", - "embassy-futures", - "embassy-rp", - "embassy-sync", - "embassy-time", - "embassy-usb", - "embassy-usb-driver", - "embassy-usb-logger", - "embedded-alloc", - "embedded-hal 0.2.7", - "embedded-io", - "futures", - "log", - "pio", - "pio-proc", - "postcard", - "ron", - "smart-leds", - "static_cell", - "tgnt", - "usb-device", - "usbd-hid", -] - [[package]] name = "lalrpop" version = "0.19.8" @@ -1225,6 +1195,36 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tangentbord1" +version = "0.1.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "embassy-executor", + "embassy-futures", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-driver", + "embassy-usb-logger", + "embedded-alloc", + "embedded-hal 0.2.7", + "embedded-io", + "futures", + "log", + "pio", + "pio-proc", + "postcard", + "ron", + "smart-leds", + "static_cell", + "tgnt", + "usb-device", + "usbd-hid", +] + [[package]] name = "term" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index 4a596df..093f30a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,8 @@ [package] -name = "itsybitsy_rp2040_keyboard" +name = "tangentbord1" version = "0.1.0" +authors = ["Joakim Hulthe "] +description = "Keyboard firmware" edition = "2021" [dependencies] diff --git a/build.rs b/build.rs index 3e917fe..e72cd13 100644 --- a/build.rs +++ b/build.rs @@ -17,7 +17,8 @@ use tgnt::layer::Layer; fn main() { memory(); - serialize_layout(); + serialize_layout("./layers-left.ron", "./src/bin/layers-left.pc"); + serialize_layout("./layers-right.ron", "./src/bin/layers-right.pc"); } fn memory() { @@ -44,16 +45,16 @@ fn memory() { //println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); } -fn serialize_layout() { - println!("cargo:rerun-if-changed=layers.ron"); +fn serialize_layout(ron_path: &str, postcard_path: &str) { + println!("cargo:rerun-if-changed={ron_path}"); - let layers = fs::read_to_string("layers.ron").expect("Failed to read layers.ron"); - let layers: Vec = ron::from_str(&layers).expect("Failed to deserialize layers.ron"); + let layers = fs::read_to_string(ron_path).expect("Failed to read .ron"); + let layers: Vec = ron::from_str(&layers).expect("Failed to deserialize .ron"); let serialized = postcard::to_stdvec(&layers).expect("Failed to serialize layers"); - File::create("./src/layers.pc") - .expect("Failed to create layers.pc") + File::create(postcard_path) + .expect("Failed to create .pc") .write_all(&serialized) - .expect("Failed to write layers.pc"); + .expect("Failed to write .pc"); } diff --git a/layers.ron b/layers-left.ron similarity index 52% rename from layers.ron rename to layers-left.ron index 41cf069..938acc3 100644 --- a/layers.ron +++ b/layers-left.ron @@ -1,7 +1,6 @@ [ Layer( buttons: [ - /* Left */ // Row 1 Key(Apostrophe), Key(Comma), @@ -27,33 +26,6 @@ Mod(LShift), Mod(LCtrl), NextLayer, - - /* Right */ - // Row 1 - Key(F), - Key(G), - Key(C), - Key(R), - Key(L), - - // Row 2 - Key(D), - Key(H), - Key(T), - Key(N), - Key(S), - - // Row 3 - Key(B), - Key(M), - Key(W), - Key(V), - Key(Z), - - // Thumbpad - PrevLayer, - Mod(RAlt), - Mod(RMod), ], ) ] diff --git a/layers-right.ron b/layers-right.ron new file mode 100644 index 0000000..ae9d288 --- /dev/null +++ b/layers-right.ron @@ -0,0 +1,31 @@ +[ + Layer( + buttons: [ + // Row 1 + Key(F), + Key(G), + Key(C), + Key(R), + Key(L), + + // Row 2 + Key(D), + Key(H), + Key(T), + Key(N), + Key(S), + + // Row 3 + Key(B), + Key(M), + Key(W), + Key(V), + Key(Z), + + // Thumbpad + PrevLayer, + Mod(RAlt), + Mod(RMod), + ], + ) +] diff --git a/run b/run index 25349d3..4f100a9 100755 --- a/run +++ b/run @@ -2,7 +2,7 @@ set -e -cargo run +cargo run --bin $1 printf "waiting for serial log" diff --git a/src/allocator.rs b/src/allocator.rs index d01e72a..b3c3c42 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -8,7 +8,7 @@ use embedded_alloc::Heap; static HEAP: Heap = Heap::empty(); pub fn init() { - const HEAP_SIZE: usize = 2048; + const HEAP_SIZE: usize = 4096; static mut HEAP_MEM: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } } diff --git a/src/bin/layers-left.pc b/src/bin/layers-left.pc new file mode 100644 index 0000000000000000000000000000000000000000..7c6f1206f2e3059405c2546da5d94f0c89653077 GIT binary patch literal 37 rcmV~$!3}^Q5CE`i, _> = postcard::from_bytes(layers) else { + log::error!("Failed to deserialize layer config"); + stall().await + }; + + let keyboard = KeyboardConfig { + layers, + pins: [ + // row 1 + board.d24.degrade(), + board.a3.degrade(), + board.a2.degrade(), + board.a1.degrade(), + board.a0.degrade(), + // row 2 + board.d25.degrade(), + board.sck.degrade(), + board.mosi.degrade(), + board.miso.degrade(), + board.d2.degrade(), + // row 3 + board.d12.degrade(), + board.d11.degrade(), + board.d10.degrade(), + board.d9.degrade(), + board.d3.degrade(), + // thumbpad + board.d7.degrade(), + board.scl.degrade(), + board.sda.degrade(), + ], + }; + + keyboard.create().await; + + for w in 0usize.. { + neopixel.write(&[wheel(w as u8)]).await; + neopixels_d5 + .write(&[ + wheel((w + 50) as u8), + wheel((w + 100) as u8), + wheel((w + 150) as u8), + wheel((w + 200) as u8), + ]) + .await; + Timer::after(Duration::from_millis(10)).await; + } +} diff --git a/src/bin/right.rs b/src/bin/right.rs new file mode 100644 index 0000000..592b400 --- /dev/null +++ b/src/bin/right.rs @@ -0,0 +1,89 @@ +//! Firmware for Tangentbord1, right half. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +extern crate alloc; +extern crate cortex_m_rt; + +use alloc::vec::Vec; +use embassy_executor::Spawner; +use embassy_rp::gpio::{Level, Output, Pin}; +use embassy_time::{Duration, Timer}; +use tangentbord1::board::Board; +use tangentbord1::keyboard::KeyboardConfig; +use tangentbord1::util::{stall, wheel}; +use tangentbord1::ws2812::{Rgb, Ws2812}; +use tangentbord1::{allocator, usb}; +use tgnt::layer::Layer; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + allocator::init(); + + let p = embassy_rp::init(Default::default()); + let board = Board::from(p); + + let _led = Output::new(board.d13, Level::High); + let _neopixel_power = Output::new(board.neopixel_power, Level::High); + + let mut neopixel = Ws2812::new(board.PIO0, board.DMA_CH0, board.neopixel.degrade()); + let mut neopixels_d5 = Ws2812::new(board.PIO1, board.DMA_CH1, board.d5.degrade()); + + neopixel.write(&[Rgb::new(0xFF, 0x00, 0x00)]).await; + usb::setup_logger_and_keyboard(board.USB).await; + neopixel.write(&[Rgb::new(0x00, 0x00, 0xFF)]).await; + + //Timer::after(Duration::from_millis(3000)).await; + + let layers = include_bytes!("layers-right.pc"); + let Ok(layers): Result, _> = postcard::from_bytes(layers) else { + log::error!("Failed to deserialize layer config"); + stall().await + }; + + let keyboard = KeyboardConfig { + layers, + pins: [ + // TODO: reconfigure these for right PCB + // row 1 + board.d24.degrade(), + board.a3.degrade(), + board.a2.degrade(), + board.a1.degrade(), + board.a0.degrade(), + // row 2 + board.d25.degrade(), + board.sck.degrade(), + board.mosi.degrade(), + board.miso.degrade(), + board.d2.degrade(), + // row 3 + board.d12.degrade(), + board.d11.degrade(), + board.d10.degrade(), + board.d9.degrade(), + board.d3.degrade(), + // thumbpad + board.d7.degrade(), + board.scl.degrade(), + board.sda.degrade(), + ], + }; + + keyboard.create().await; + + for w in 0usize.. { + neopixel.write(&[wheel(w as u8)]).await; + neopixels_d5 + .write(&[ + wheel((w + 50) as u8), + wheel((w + 100) as u8), + wheel((w + 150) as u8), + wheel((w + 200) as u8), + ]) + .await; + Timer::after(Duration::from_millis(10)).await; + } +} diff --git a/src/board.rs b/src/board.rs index bd64013..5e7c346 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,8 +1,26 @@ -use embassy_rp::peripherals::*; +use embassy_rp::{peripherals::*, Peripherals}; /// Pinouts for the ItsyBitsy -#[allow(dead_code)] +#[allow(dead_code, non_snake_case)] pub struct Board { + pub USB: USB, + pub UART0: UART0, + pub UART1: UART1, + pub PIO0: PIO0, + pub PIO1: PIO1, + pub DMA_CH0: DMA_CH0, + pub DMA_CH1: DMA_CH1, + pub DMA_CH2: DMA_CH2, + pub DMA_CH3: DMA_CH3, + pub DMA_CH4: DMA_CH4, + pub DMA_CH5: DMA_CH5, + pub DMA_CH6: DMA_CH6, + pub DMA_CH7: DMA_CH7, + pub DMA_CH8: DMA_CH8, + pub DMA_CH9: DMA_CH9, + pub DMA_CH10: DMA_CH10, + + // pins pub a0: PIN_26, pub a1: PIN_27, pub a2: PIN_28, @@ -29,3 +47,53 @@ pub struct Board { pub neopixel: PIN_17, pub neopixel_power: PIN_16, } + +impl From for Board { + fn from(p: Peripherals) -> Self { + Board { + USB: p.USB, + UART0: p.UART0, + UART1: p.UART1, + PIO0: p.PIO0, + PIO1: p.PIO1, + DMA_CH0: p.DMA_CH0, + DMA_CH1: p.DMA_CH1, + DMA_CH2: p.DMA_CH2, + DMA_CH3: p.DMA_CH3, + DMA_CH4: p.DMA_CH4, + DMA_CH5: p.DMA_CH5, + DMA_CH6: p.DMA_CH6, + DMA_CH7: p.DMA_CH7, + DMA_CH8: p.DMA_CH8, + DMA_CH9: p.DMA_CH9, + DMA_CH10: p.DMA_CH10, + + // pins + a0: p.PIN_26, + a1: p.PIN_27, + a2: p.PIN_28, + a3: p.PIN_29, + d24: p.PIN_24, + d25: p.PIN_25, + sck: p.PIN_18, + mosi: p.PIN_19, + miso: p.PIN_20, + d2: p.PIN_12, + d3: p.PIN_5, + d4: p.PIN_4, + rx: p.PIN_1, + tx: p.PIN_0, + sda: p.PIN_2, + scl: p.PIN_3, + d5: p.PIN_14, + d7: p.PIN_6, + d9: p.PIN_7, + d10: p.PIN_8, + d11: p.PIN_9, + d12: p.PIN_10, + d13: p.PIN_11, + neopixel: p.PIN_17, + neopixel_power: p.PIN_16, + } + } +} diff --git a/src/keyboard.rs b/src/keyboard.rs index 9f5d78f..320a91a 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -3,7 +3,9 @@ use core::sync::atomic::{AtomicU16, Ordering}; use alloc::{boxed::Box, vec::Vec}; use embassy_executor::Spawner; use embassy_rp::gpio::{AnyPin, Input, Pin, Pull}; -use log::{error, warn}; +use embassy_time::{Duration, Timer}; +use futures::{select_biased, FutureExt}; +use log::{debug, error, info, warn}; use tgnt::{button::Button, layer::Layer}; use crate::usb::keyboard::KB_REPORT; @@ -24,6 +26,11 @@ impl KeyboardConfig { return; } + info!( + "setting up keyboard layout with {} layer(s)", + self.layers.len() + ); + let layers = Box::leak(self.layers.into_boxed_slice()); for (i, layer) in layers.iter().enumerate() { if layer.buttons.len() != SWITCH_COUNT { @@ -43,7 +50,10 @@ impl KeyboardConfig { } } +const MOD_TAP_TIME: Duration = Duration::from_millis(100); const SWITCH_COUNT: usize = 18; + +/// Task for monitoring a single switch pin, and handling button presses. #[embassy_executor::task(pool_size = 18)] async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) -> ! { let _pin_nr = pin.pin(); @@ -51,27 +61,39 @@ async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) - loop { // pins are pull-up, so when the switch is pressed they are brought low. pin.wait_for_low().await; + + // TODO: do we need debouncing? + + // get current layer let mut current_layer = CURRENT_LAYER.load(Ordering::Relaxed); let layer_count = layers.len() as u16; if current_layer >= layer_count { error!("current layer was out of bounds for some reason ({current_layer})"); current_layer = 0; } - let Some(Layer { buttons }) = layers.get(usize::from(current_layer)) else { error!("current layer was out of bounds for some reason ({current_layer})"); CURRENT_LAYER.store(0, Ordering::Relaxed); continue; }; + // and current button let Some(button) = buttons.get(switch_num) else { + warn!("no button defined for switch {switch_num}"); continue; }; + debug!("switch {switch_num} button {button:?} pressed"); + + let wait_for_release = async { + pin.wait_for_high().await; + debug!("switch {switch_num} button {button:?} released"); + }; + match button { &Button::Key(key) => { KB_REPORT.lock().await.press_key(key); - pin.wait_for_high().await; + wait_for_release.await; KB_REPORT.lock().await.release_key(key); continue; } @@ -83,7 +105,19 @@ async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) - //continue; } Button::ModTap { keycode, modifier } => { - // TODO + select_biased! { + _ = Timer::after(MOD_TAP_TIME).fuse() => { + // TODO: Modifier + pin.wait_for_high().await; + continue; + } + _ = wait_for_release.fuse() => { + KB_REPORT.lock().await.press_key(*keycode); + Timer::after(Duration::from_millis(10)).await; + KB_REPORT.lock().await.release_key(*keycode); + continue; + } + } } Button::NextLayer => { let next_layer = (current_layer + 1) % layer_count; @@ -96,7 +130,7 @@ async fn switch_task(switch_num: usize, pin: AnyPin, layers: &'static [Layer]) - Button::None => {} } - pin.wait_for_high().await; + wait_for_release.await; } } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fdf3a1d --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,13 @@ +#![no_std] +#![feature(type_alias_impl_trait)] + +extern crate alloc; + +pub mod allocator; +pub mod board; +pub mod keyboard; +pub mod neopixel; +pub mod panic_handler; +pub mod usb; +pub mod util; +pub mod ws2812; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index fe32a53..0000000 --- a/src/main.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! # GPIO 'Blinky' Example -//! -//! Blinks the LED on a Adafruit itsy-bitsy RP2040 board -//! -//! It may need to be adapted to your particular board layout and/or pin assignment. -//! -//! See the `Cargo.toml` file for Copyright and license details. - -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -extern crate alloc; -extern crate cortex_m_rt; - -mod allocator; -mod board; -mod keyboard; -mod neopixel; -mod panic_handler; -mod usb; -mod util; -mod ws2812; - -use alloc::vec::Vec; -use board::Board; -use embassy_executor::Spawner; -use embassy_rp::gpio::{Level, Output, Pin}; -use embassy_time::{Duration, Timer}; -use tgnt::layer::Layer; -use ws2812::Rgb; - -use crate::keyboard::KeyboardConfig; - -#[embassy_executor::main] -async fn main(spawner: Spawner) { - allocator::init(); - - let p = embassy_rp::init(Default::default()); - - let board = Board { - a0: p.PIN_26, - a1: p.PIN_27, - a2: p.PIN_28, - a3: p.PIN_29, - d24: p.PIN_24, - d25: p.PIN_25, - sck: p.PIN_18, - mosi: p.PIN_19, - miso: p.PIN_20, - d2: p.PIN_12, - d3: p.PIN_5, - d4: p.PIN_4, - rx: p.PIN_1, - tx: p.PIN_0, - sda: p.PIN_2, - scl: p.PIN_3, - d5: p.PIN_14, - d7: p.PIN_6, - d9: p.PIN_7, - d10: p.PIN_8, - d11: p.PIN_9, - d12: p.PIN_10, - d13: p.PIN_11, - neopixel: p.PIN_17, - neopixel_power: p.PIN_16, - }; - - //let mut led = Output::new(board.d13, Level::Low); - let _neopixel_power = Output::new(board.neopixel_power, Level::High); - - let mut neopixel = ws2812::Ws2812::new(p.PIO0, p.DMA_CH0, board.neopixel.degrade()); - let mut neopixels_d5 = ws2812::Ws2812::new(p.PIO1, p.DMA_CH1, board.d5.degrade()); - - neopixel.write(&[Rgb::new(0xb7, 0x31, 0x2c)]).await; - - let mut builder = usb::builder(p.USB); - - usb::logger::setup(&mut builder).await; - - neopixel.write(&[Rgb::new(0xf0, 0xd0, 0x20)]).await; - - log::error!("log_level: error"); - log::warn!("log_level: warn"); - log::info!("log_level: info"); - log::debug!("log_level: debug"); - log::trace!("log_level: trace"); - - usb::keyboard::setup(&mut builder).await; - - let usb = builder.build(); - - spawner.must_spawn(usb::run(usb)); - - Timer::after(Duration::from_millis(3000)).await; - - let layers = include_bytes!("layers.pc"); - let Ok(layers): Result, _> = postcard::from_bytes(layers) else { - log::error!("Failed to deserialize layer config"); - loop_forever().await - }; - - let keyboard = KeyboardConfig { - layers, - pins: [ - // row 1 - board.d24.degrade(), - board.a3.degrade(), - board.a2.degrade(), - board.a1.degrade(), - board.a0.degrade(), - // row 2 - board.d25.degrade(), - board.sck.degrade(), - board.mosi.degrade(), - board.miso.degrade(), - board.d2.degrade(), - // row 3 - board.d12.degrade(), - board.d11.degrade(), - board.d10.degrade(), - board.d9.degrade(), - board.d3.degrade(), - // thumbpad - board.d7.degrade(), - board.scl.degrade(), - board.sda.degrade(), - ], - }; - - keyboard.create().await; - - for w in 0usize.. { - neopixel.write(&[wheel(w as u8)]).await; - neopixels_d5 - .write(&[ - wheel((w + 50) as u8), - wheel((w + 100) as u8), - wheel((w + 150) as u8), - wheel((w + 200) as u8), - ]) - .await; - Timer::after(Duration::from_millis(10)).await; - } -} - -async fn loop_forever() -> ! { - loop { - Timer::after(Duration::from_secs(1)).await; - } -} - -/// 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) -> Rgb { - wheel_pos = 255 - wheel_pos; - if wheel_pos < 85 { - return Rgb::new(255 - wheel_pos * 3, 0, wheel_pos * 3); - } - if wheel_pos < 170 { - wheel_pos -= 85; - return Rgb::new(0, wheel_pos * 3, 255 - wheel_pos * 3); - } - wheel_pos -= 170; - Rgb::new(wheel_pos * 3, 255 - wheel_pos * 3, 0) -} diff --git a/src/usb.rs b/src/usb.rs index e88e34c..d57d234 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -1,3 +1,4 @@ +use embassy_executor::Spawner; use embassy_rp::{interrupt, peripherals::USB, usb::Driver}; use embassy_usb::{Builder, Config, UsbDevice}; use static_cell::StaticCell; @@ -16,6 +17,21 @@ struct State { static STATE: StaticCell = StaticCell::new(); +pub async fn setup_logger_and_keyboard(usb: USB) { + let mut builder = builder(usb); + logger::setup(&mut builder).await; + + log::error!("log_level: error"); + log::warn!("log_level: warn"); + log::info!("log_level: info"); + log::debug!("log_level: debug"); + log::trace!("log_level: trace"); + + keyboard::setup(&mut builder).await; + let usb = builder.build(); + Spawner::for_current_executor().await.must_spawn(run(usb)); +} + pub fn builder(usb: USB) -> Builder<'static, Driver<'static, USB>> { let state = STATE.init(State { device_descriptor: [0; 256], diff --git a/src/usb/keyboard.rs b/src/usb/keyboard.rs index fd4eb6f..22711af 100644 --- a/src/usb/keyboard.rs +++ b/src/usb/keyboard.rs @@ -99,7 +99,7 @@ async fn keyboard_test(mut stream: HidStream, _handler: &'static Handler) -> Res let report = KB_REPORT.lock().await.clone(); if report.keycodes != EMPTY_KEYBOARD_REPORT.keycodes { - log::debug!("keys: {:x?}", report.keycodes); + log::trace!("keys: {:x?}", report.keycodes); } #[cfg(feature = "n-key-rollover")] diff --git a/src/usb/keyboard/report.rs b/src/usb/keyboard/report.rs index 1fbf482..c65ed38 100644 --- a/src/usb/keyboard/report.rs +++ b/src/usb/keyboard/report.rs @@ -36,7 +36,6 @@ pub const EMPTY_KEYBOARD_REPORT: KeyboardReport = KeyboardReport { impl KeyboardReport { pub fn set_key(&mut self, key: Key, pressed: bool) { let keycode = u8::from(key); - log::debug!("setting key: {key:?} ({keycode:x})"); let byte = keycode >> 3; let bit = keycode & 0b111; let mask = 1 << bit; @@ -48,7 +47,7 @@ impl KeyboardReport { *k &= !mask; } } else { - log::warn!("Tried to set out-of-range keycode: {keycode:x}"); + log::warn!("Tried to set out-of-range keycode: 0x{keycode:x}"); } } diff --git a/src/util.rs b/src/util.rs index d7bf851..18b5652 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,3 +1,27 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_time::{Duration, Timer}; + +use crate::ws2812::Rgb; pub type CS = CriticalSectionRawMutex; + +pub async fn stall() -> ! { + loop { + Timer::after(Duration::from_secs(1)).await; + } +} + +/// Input a value 0 to 255 to get a color value +// The colours are a transition r - g - b - back to r. +pub fn wheel(mut wheel_pos: u8) -> Rgb { + wheel_pos = 255 - wheel_pos; + if wheel_pos < 85 { + return Rgb::new(255 - wheel_pos * 3, 0, wheel_pos * 3); + } + if wheel_pos < 170 { + wheel_pos -= 85; + return Rgb::new(0, wheel_pos * 3, 255 - wheel_pos * 3); + } + wheel_pos -= 170; + Rgb::new(wheel_pos * 3, 255 - wheel_pos * 3, 0) +}