Skip to content

Instantly share code, notes, and snippets.

@riskable
Last active April 23, 2022 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riskable/2621da7110e30f407437030c00f7857c to your computer and use it in GitHub Desktop.
Save riskable/2621da7110e30f407437030c00f7857c to your computer and use it in GitHub Desktop.
/// Configuration structs; separate from config.rs so we can use them in build.rs
/// without having to duplicate them
use serde::{Deserialize, Serialize};
// This lets us generate a userconfig.rs from inside build.rs that gets include!(concat!()) inside config.rs:
macro_rules! add_const_gen {
(
$(#[$meta:meta])*
pub struct $struct_name:ident {
$(
$(#[$field_meta:meta])*
$field_vis:vis $field_name:ident : $field_type:ty
),*$(,)+
}
) => {
$(#[$meta])*
pub struct $struct_name {
$(
$(#[$field_meta])*
pub $field_name : $field_type,
)*
}
impl $struct_name {
#[allow(dead_code)]
fn field_names() -> &'static [&'static str] {
static NAMES: &'static [&'static str] = &[$(stringify!($field_name)),*];
NAMES
}
#[allow(dead_code)]
fn gen_meta_tuple(&self, field: &'static str) -> (&str, &str, &str) {
match field {
$(stringify!($field_name) => {
(
stringify!($struct_name),
stringify!($field_name),
stringify!($field_type),
)
}),*
_ => ("","","")
}
}
}
};
(
$(#[$meta:meta])*
pub struct $struct_name:ident <$life:lifetime> {
$(
$(#[$field_meta:meta])*
$field_vis:vis $field_name:ident : $field_type:ty
),*$(,)+
}
) => {
$(#[$meta])*
pub struct $struct_name <$life> {
$(
$(#[$field_meta])*
pub $field_name : $field_type,
)*
}
impl $struct_name <'_> {
#[allow(dead_code)]
fn field_names() -> &'static [&'static str] {
static NAMES: &'static [&'static str] = &[$(stringify!($field_name)),*];
NAMES
}
#[allow(dead_code)]
fn gen_meta_tuple(&self, field: &'static str) -> (&str, &str, &str) {
match field {
$(stringify!($field_name) => {
(
stringify!($struct_name),
stringify!($field_name),
stringify!($field_type),
)
}),*
_ => ("","","")
}
}
}
}
}
add_const_gen! {
#[derive(Debug, Serialize, Deserialize)]
pub struct HardwareConfig {
pub storage_size: u32,
pub test: &'static str,
}
}
add_const_gen! {
/// Configuration items related to keys, sensors, and the rotary encoder
#[derive(Debug, Serialize, Deserialize)]
pub struct KeyboardConfig<'a> {
/// Millivolts difference where we consider it a Press()
pub north_down: u8,
/// Millivolts difference where we consider it a Press()
pub actuation_threshold: u16,
/// Millivolts above the actuation threshold where we consider it a Release() (prevents bouncing)
pub release_threshold: u16,
/// Millivolt values below this value will be ignored (so we can skip mux pins connected to ground)
pub ignore_below: u16,
/// How often to check to see if the default mV values need to be adjusted (cycles)
pub recalibration_rate: u32,
/// Total number of multiplexers on this keyboard
pub num_multiplexers: usize,
/// Total number of channels per multiplexer
pub mux_channels: usize,
/// The USB VID the keyboard will identify itself with
pub usb_vid: u16,
/// The USB PID the keyboard will identify itself with
pub usb_pid: u16,
#[serde(borrow)]
pub test: &'a str,
}
}
add_const_gen! {
/// Configuration items related to mouse emulation
#[derive(Debug, Serialize, Deserialize)]
pub struct MouseConfig {
/// Amount of units (aka lines) to scroll per press/rotary encoder movement
pub scroll_amount: u8,
}
}
add_const_gen! {
/// Configuration items related to a rotary encoder
#[derive(Debug, Serialize, Deserialize)]
pub struct EncoderConfig {
/// The multiplexer the encoder sensors are connected to
pub mux: usize,
/// Millivolts difference required before we consider the encoder moved in either direction
pub resolution: u16,
/// Millivolts difference before we consider it an encoder Press()
pub press_threshold: u16,
/// Channel on the multiplexer where the encoder's first sensor resides
pub channel1: usize,
/// Channel on the multiplexer where the encoder's second sensor resides
pub channel2: usize,
/// Virtual channel on the multiplexer where Press() events get defined
pub press_channel: usize,
}
}
add_const_gen! {
/// Configuration items related to the WS2812B-B RGB LEDs
#[derive(Debug, Serialize, Deserialize)]
pub struct LedsConfig {
/// Default brightness of the LEDs (0-255)
pub brightness: u8,
/// Max brightness of the LEDs
pub max_brightness: u8,
/// Amount to change brightness when increasing or decreasing it
pub step: u8,
/// Total number of LEDs on or attached to the keyboard (70 plus however many you've connected)
pub num_leds: usize,
/// Rate (in hz) at which the LEDs are updated
pub speed: u32,
}
}
// TODO: Make this more display-agnostic so it can work with anything
add_const_gen! {
/// Configuration items related to the MAX7219 displays/matrices
#[derive(Debug, Serialize, Deserialize)]
pub struct DisplayConfig {
/// Total number of MAX7219 matrices connected to the keyboard
pub num_matrices: usize,
/// Brightness (aka display intensity) (0-8)
pub brightness: u8,
/// Max brightness overall (0-8)
pub max_brightness: u8,
/// Maximum amount of characters we'll buffer (uses up RAM so don't make it too big)
pub buffer_length: usize,
/// If the display is upside down (0 or 1)
pub vertical_flip: u8,
/// If the display needs to be mirrored (0 or 1)
pub mirror: u8,
/// How often (Hz) the display should be re-drawn
pub refresh_interval: u32,
}
}
add_const_gen! {
/// Configuration items related to mouse emulation
#[derive(Debug, Serialize, Deserialize)]
pub struct InfraredConfig {
/// Amount of units (aka lines) to scroll per press/rotary encoder movement
pub encoding: u8,
/// Imaginary multiplexer that holds IR remote button mappings
pub mux: usize,
// /// The sample rate (usually a fixed value based on the IR receiver)
// pub samplerate: u32,
}
}
add_const_gen! {
/// Configuration items related to development stuff
#[derive(Debug, Serialize, Deserialize)]
pub struct DevConfig {
/// Minimum amount of time to wait before sending debug messages to the debugger
pub debug_refresh_interval: u16,
}
}
/// Central location for referencing and updating runtime settings
#[derive(Debug, Serialize, Deserialize)]
pub struct Config<'a> {
/// Keyboard configuration items
#[serde(borrow)]
pub keyboard: KeyboardConfig<'a>,
// pub keyboard: KeyboardConfig<'a>,
/// Mouse configuration items
pub mouse: MouseConfig,
/// Encoder configuration items
pub encoder: EncoderConfig,
/// LED configuration items
pub leds: LedsConfig,
/// Display (MAX7219) configuration items
pub display: DisplayConfig,
/// Remote control (infrared) configuration items
pub infrared: InfraredConfig,
/// Development configuration items (e.g. debug stuff)
pub dev: DevConfig,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment