Skip to content

Commit

Permalink
Merge pull request #9 from daystram/feat/configurable-keyboard
Browse files Browse the repository at this point in the history
Configurable keyboard and layout
  • Loading branch information
daystram authored Jul 22, 2024
2 parents 78749ea + d97ab5f commit b487572
Show file tree
Hide file tree
Showing 16 changed files with 589 additions and 195 deletions.
2 changes: 2 additions & 0 deletions .envrc.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export KEYBOARD=default
export LAYOUT=default
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ target/

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

.envrc

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ usbd-human-interface-device = "0.5.0"
smart-leds = "0.3.0"
ws2812-pio = "0.8.0"
enum-map = "2.7.3"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [
"cfg(keyboard, values(any()))",
"cfg(layout, values(any()))",
] }
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,18 @@ fn main() {
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x");

// Select keyboard.
println!("cargo::rerun-if-env-changed=KEYBOARD");
println!(
"cargo::rustc-cfg=keyboard=\"{}\"",
env::var("KEYBOARD").expect("KEYBOARD env var unset: specify the selected keyboard")
);

// Select layout.
println!("cargo::rerun-if-env-changed=LAYOUT");
println!(
"cargo::rustc-cfg=layout=\"{}\"",
env::var("LAYOUT").expect("LAYOUT env var unset: specify the selected layout")
);
}
24 changes: 24 additions & 0 deletions src/heartbeat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use alloc::boxed::Box;
use embedded_hal::pwm::SetDutyCycle;
use hal::gpio;

use crate::util;

const MAX_PWM_POWER: u16 = 0x6000;

pub struct HeartbeatLED {
pin: Box<dyn SetDutyCycle<Error = gpio::Error>>,
}

impl HeartbeatLED {
pub fn new(pin: Box<dyn SetDutyCycle<Error = gpio::Error>>) -> Self {
return HeartbeatLED { pin };
}

pub async fn cycle(&mut self) {
loop {
util::lerp(&mut self.pin, 0, MAX_PWM_POWER, 200, 10).await;
util::lerp(&mut self.pin, MAX_PWM_POWER, 0, 200, 10).await;
}
}
}
2 changes: 1 addition & 1 deletion src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ pub enum Control {
RGBDirectionToggle,
}

pub trait LayerIndex: Copy + Into<usize> + Format {}
pub trait LayerIndex: Copy + Default + PartialEq + PartialOrd + Format + Into<usize> {}

#[derive(Clone, Copy, Debug, Format, PartialEq)]
pub enum Edge {
Expand Down
63 changes: 63 additions & 0 deletions src/keyboard/default/layout/default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#![allow(dead_code)]
use defmt::Format;
use enum_map::enum_map;

use crate::{
key::{
Action::{Control as C, Key as K, LayerModifier as LM, Pass as ___________},
Control, Key, LayerIndex,
},
keyboard::KeyboardConfiguration,
processor::mapper::InputMap,
rotary::Direction,
};

pub const LAYER_COUNT: usize = 2;

#[derive(Clone, Copy, PartialEq, PartialOrd, Format)]
pub enum Layer {
Base,
Function1,
}

impl LayerIndex for Layer {}

impl Into<usize> for Layer {
fn into(self) -> usize {
self as usize
}
}

impl Default for Layer {
fn default() -> Self {
return Layer::Base;
}
}

#[rustfmt::skip]
pub fn get_input_map() -> InputMap<{ <super::super::Keyboard as KeyboardConfiguration>::LAYER_COUNT }, { <super::super::Keyboard as KeyboardConfiguration>::KEY_MATRIX_ROW_COUNT }, { <super::super::Keyboard as KeyboardConfiguration>::KEY_MATRIX_COL_COUNT }, <super::super::Keyboard as KeyboardConfiguration>::Layer> {
return InputMap::new(
[
[
[K(Key::A), K(Key::B)],
[___________, LM(Layer::Function1)],
],
[
[K(Key::C), K(Key::D)],
[C(Control::RGBAnimationNext), ___________],
],
],
[
enum_map! {
Direction::Clockwise => C(Control::RGBBrightnessUp),
Direction::CounterClockwise => C(Control::RGBBrightnessDown),
_ => ___________,
},
enum_map! {
Direction::Clockwise => C(Control::RGBSpeedUp),
Direction::CounterClockwise => C(Control::RGBSpeedDown),
_ => ___________,
},
],
);
}
10 changes: 10 additions & 0 deletions src/keyboard/default/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[cfg(layout = "default")]
mod default;
#[cfg(layout = "default")]
use default as selected_layout;

pub use selected_layout::LAYER_COUNT;

pub use selected_layout::Layer;

pub use selected_layout::get_input_map;
107 changes: 107 additions & 0 deletions src/keyboard/default/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
pub mod layout;

use alloc::boxed::Box;
use hal::{fugit::HertzU32, gpio, pac, pio, pwm};
use ws2812_pio::Ws2812Direct;

use crate::{
heartbeat::HeartbeatLED,
keyboard::KeyboardConfiguration,
matrix::BasicVerticalSwitchMatrix,
processor::events::rgb::RGBMatrix,
rotary::{Mode, RotaryEncoder},
};

const ENABLE_HEARTBEAT_LED: bool = true;
const ENABLE_KEY_MATRIX: bool = true;
const ENABLE_ROTARY_ENCODER: bool = true;
const ENABLE_RGB_MATRIX: bool = true;

pub struct Keyboard {}

impl KeyboardConfiguration for Keyboard {
const KEY_MATRIX_ROW_COUNT: usize = 2;
const KEY_MATRIX_COL_COUNT: usize = 2;

const RGB_MATRIX_LED_COUNT: usize = 4;

fn init(
pins: gpio::Pins,
mut slices: pwm::Slices,
mut pio0: pio::PIO<pac::PIO0>,
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
clock_freq: HertzU32,
) -> (
Option<
BasicVerticalSwitchMatrix<
{ Self::KEY_MATRIX_ROW_COUNT },
{ Self::KEY_MATRIX_COL_COUNT },
>,
>,
Option<RotaryEncoder>,
Option<HeartbeatLED>,
Option<
RGBMatrix<
{ Self::RGB_MATRIX_LED_COUNT },
Ws2812Direct<
pac::PIO0,
pio::SM0,
gpio::Pin<gpio::bank0::Gpio28, gpio::FunctionPio0, gpio::PullDown>,
>,
>,
>,
) {
#[rustfmt::skip]
let key_matrix = if ENABLE_KEY_MATRIX {
Some(BasicVerticalSwitchMatrix::new(
[
Box::new(pins.gpio21.into_pull_down_input()),
Box::new(pins.gpio20.into_pull_down_input()),
],
[
Box::new(pins.gpio0.into_push_pull_output()),
Box::new(pins.gpio1.into_push_pull_output()),
],
))
} else {
None
};

let rotary_encoder = if ENABLE_ROTARY_ENCODER {
Some(RotaryEncoder::new(
Box::new(pins.gpio15.into_pull_up_input()),
Box::new(pins.gpio17.into_pull_up_input()),
Box::new(pins.gpio16.into_push_pull_output()),
Mode::DentHighPrecision,
))
} else {
None
};

let heartbeat_led = if ENABLE_HEARTBEAT_LED {
slices.pwm6.set_ph_correct();
slices.pwm6.enable();
slices.pwm6.channel_b.output_to(
pins.gpio29
.into_push_pull_output_in_state(gpio::PinState::Low),
);
Some(HeartbeatLED::new(Box::new(slices.pwm6.channel_b)))
} else {
None
};

let rgb_matrix = if ENABLE_RGB_MATRIX {
let ws = ws2812_pio::Ws2812Direct::new(
pins.gpio28.into_function(),
&mut pio0,
sm0,
clock_freq,
);
Some(RGBMatrix::<{ Keyboard::RGB_MATRIX_LED_COUNT }, _>::new(ws))
} else {
None
};

(key_matrix, rotary_encoder, heartbeat_led, rgb_matrix)
}
}
44 changes: 23 additions & 21 deletions src/config.rs → src/keyboard/kb_dev/layout/default.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(dead_code)]
use defmt::Format;
use enum_map::enum_map;

Expand All @@ -6,19 +7,36 @@ use crate::{
Action::{Control as C, Key as K, LayerModifier as LM, Pass as ___________},
Control, Key, LayerIndex,
},
keyboard::KeyboardConfiguration,
processor::mapper::InputMap,
rotary::Direction,
};

pub const LAYER_COUNT: usize = 3;
pub const KEY_MATRIX_ROW_COUNT: usize = 5;
pub const KEY_MATRIX_COL_COUNT: usize = 15;

pub const LED_COUNT: usize = 67;
#[derive(Clone, Copy, PartialEq, PartialOrd, Format)]
pub enum Layer {
Base,
Function1,
Function2,
}

impl LayerIndex for Layer {}

impl Into<usize> for Layer {
fn into(self) -> usize {
self as usize
}
}

impl Default for Layer {
fn default() -> Self {
return Layer::Base;
}
}

#[rustfmt::skip]
pub fn build_input_map(
) -> InputMap<{ LAYER_COUNT }, { KEY_MATRIX_ROW_COUNT }, { KEY_MATRIX_COL_COUNT }, Layer> {
pub fn get_input_map() -> InputMap<{ <super::super::Keyboard as KeyboardConfiguration>::LAYER_COUNT }, { <super::super::Keyboard as KeyboardConfiguration>::KEY_MATRIX_ROW_COUNT }, { <super::super::Keyboard as KeyboardConfiguration>::KEY_MATRIX_COL_COUNT }, <super::super::Keyboard as KeyboardConfiguration>::Layer> {
return InputMap::new(
[
[
Expand Down Expand Up @@ -62,19 +80,3 @@ pub fn build_input_map(
],
);
}

#[allow(dead_code)]
#[derive(Clone, Copy, PartialEq, PartialOrd, Format)]
pub enum Layer {
Base,
Function1,
Function2,
}

impl LayerIndex for Layer {}

impl Into<usize> for Layer {
fn into(self) -> usize {
self as usize
}
}
10 changes: 10 additions & 0 deletions src/keyboard/kb_dev/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[cfg(layout = "default")]
mod default;
#[cfg(layout = "default")]
use default as selected_layout;

pub use selected_layout::LAYER_COUNT;

pub use selected_layout::Layer;

pub use selected_layout::get_input_map;
Loading

0 comments on commit b487572

Please sign in to comment.