148 lines
4.3 KiB
Rust
148 lines
4.3 KiB
Rust
//! Hardware configuration and timing constants for the CMDR Keyboard 42.
|
|
|
|
/// External crystal frequency (Hz).
|
|
pub const XTAL_FREQ_HZ: u32 = 12_000_000;
|
|
|
|
/// Debounce scans required before a key state toggles.
|
|
pub const MATRIX_DEBOUNCE_SCANS_PRESS: u8 = 2;
|
|
pub const MATRIX_DEBOUNCE_SCANS_RELEASE: u8 = 3;
|
|
|
|
/// Initial scan iterations before trusting key state.
|
|
pub const INITIAL_SCAN_PASSES: usize = 50;
|
|
|
|
/// Button matrix geometry.
|
|
pub const KEY_ROWS: usize = 4;
|
|
pub const KEY_COLS: usize = 12;
|
|
pub const NUMBER_OF_KEYS: usize = KEY_ROWS * KEY_COLS;
|
|
|
|
/// USB identification constants.
|
|
pub mod usb {
|
|
pub const VID: u16 = 0x1209;
|
|
pub const PID: u16 = 0x0001;
|
|
pub const MANUFACTURER: &str = "CMtec";
|
|
pub const PRODUCT: &str = "CMDR Keyboard 42";
|
|
pub const SERIAL_NUMBER: &str = "0001";
|
|
}
|
|
|
|
/// Timing cadence helpers used throughout the firmware.
|
|
pub mod timers {
|
|
pub const USB_REPORT_INTERVAL_MS: u32 = 10;
|
|
pub const USB_TICK_INTERVAL_US: u32 = 250;
|
|
pub const STATUS_LED_INTERVAL_MS: u32 = 4;
|
|
pub const IDLE_TIMEOUT_MS: u32 = 5_000;
|
|
}
|
|
|
|
/// Physical GPIO assignments for the RP2040.
|
|
pub mod pins {
|
|
pub const BUTTON_ROW_0: u8 = 0;
|
|
pub const BUTTON_ROW_1: u8 = 1;
|
|
pub const BUTTON_ROW_2: u8 = 29;
|
|
pub const BUTTON_ROW_3: u8 = 28;
|
|
|
|
pub const BUTTON_COL_0: u8 = 12;
|
|
pub const BUTTON_COL_1: u8 = 13;
|
|
pub const BUTTON_COL_2: u8 = 14;
|
|
pub const BUTTON_COL_3: u8 = 15;
|
|
pub const BUTTON_COL_4: u8 = 26;
|
|
pub const BUTTON_COL_5: u8 = 27;
|
|
pub const BUTTON_COL_6: u8 = 7;
|
|
pub const BUTTON_COL_7: u8 = 8;
|
|
pub const BUTTON_COL_8: u8 = 6;
|
|
pub const BUTTON_COL_9: u8 = 9;
|
|
pub const BUTTON_COL_10: u8 = 10;
|
|
pub const BUTTON_COL_11: u8 = 11;
|
|
|
|
pub const STATUS_LED: u8 = 16;
|
|
}
|
|
|
|
/// Convenience macro mirroring the joystick repository for fetching typed pins.
|
|
#[macro_export]
|
|
macro_rules! get_pin {
|
|
($pins:expr, button_row_0) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_ROW_0;
|
|
$pins.gpio0
|
|
}};
|
|
($pins:expr, button_row_1) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_ROW_1;
|
|
$pins.gpio1
|
|
}};
|
|
($pins:expr, button_row_2) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_ROW_2;
|
|
$pins.gpio29
|
|
}};
|
|
($pins:expr, button_row_3) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_ROW_3;
|
|
$pins.gpio28
|
|
}};
|
|
($pins:expr, button_col_0) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_0;
|
|
$pins.gpio12
|
|
}};
|
|
($pins:expr, button_col_1) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_1;
|
|
$pins.gpio13
|
|
}};
|
|
($pins:expr, button_col_2) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_2;
|
|
$pins.gpio14
|
|
}};
|
|
($pins:expr, button_col_3) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_3;
|
|
$pins.gpio15
|
|
}};
|
|
($pins:expr, button_col_4) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_4;
|
|
$pins.gpio26
|
|
}};
|
|
($pins:expr, button_col_5) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_5;
|
|
$pins.gpio27
|
|
}};
|
|
($pins:expr, button_col_6) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_6;
|
|
$pins.gpio7
|
|
}};
|
|
($pins:expr, button_col_7) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_7;
|
|
$pins.gpio8
|
|
}};
|
|
($pins:expr, button_col_8) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_8;
|
|
$pins.gpio6
|
|
}};
|
|
($pins:expr, button_col_9) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_9;
|
|
$pins.gpio9
|
|
}};
|
|
($pins:expr, button_col_10) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_10;
|
|
$pins.gpio10
|
|
}};
|
|
($pins:expr, button_col_11) => {{
|
|
const _: u8 = $crate::hardware::pins::BUTTON_COL_11;
|
|
$pins.gpio11
|
|
}};
|
|
($pins:expr, status_led) => {{
|
|
const _: u8 = $crate::hardware::pins::STATUS_LED;
|
|
$pins.gpio16
|
|
}};
|
|
}
|
|
|
|
#[cfg(all(test, feature = "std"))]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn number_of_keys_matches_rows_and_cols() {
|
|
assert_eq!(NUMBER_OF_KEYS, KEY_ROWS * KEY_COLS);
|
|
}
|
|
|
|
#[test]
|
|
fn usb_metadata_is_consistent() {
|
|
assert_ne!(usb::VID, 0);
|
|
assert_ne!(usb::PID, 0);
|
|
assert!(!usb::MANUFACTURER.is_empty());
|
|
assert!(!usb::PRODUCT.is_empty());
|
|
}
|
|
}
|