Splitted out layout file
This commit is contained in:
parent
5ae9e09667
commit
24de6a5109
171
rp2040/src/layout.rs
Normal file
171
rp2040/src/layout.rs
Normal file
@ -0,0 +1,171 @@
|
||||
// Button index map:
|
||||
// ------------------------------------- -------------------------------------
|
||||
// | 0 | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 10 | 11 |
|
||||
// | 12 | 13 | 14 | 15 | 16 | 17 | | 18 | 19 | 20 | 21 | 22 | 23 |
|
||||
// | 24 | 25 | 26 | 27 | 28 | 29 | | 30 | 31 | 32 | 33 | 34 | 35 |
|
||||
// ------------------| 36 | 37 | 38 | | 39 | 40 | 41 |------------------
|
||||
// ------------------- -------------------
|
||||
//
|
||||
// Swedish keymap conversion table:
|
||||
// US Swedish
|
||||
// --------------------------
|
||||
// Grave §
|
||||
// Semicolon ö
|
||||
// Apostrophe ä
|
||||
// LeftBrace å
|
||||
// ForwardSlash -
|
||||
// NonUSBackslash <
|
||||
// Equal ´
|
||||
// Backslash '
|
||||
// RightBrace ^
|
||||
// Minus +
|
||||
// LeftAlt Alt
|
||||
// RightAlt AltGr
|
||||
|
||||
use crate::NUMBER_OF_KEYS;
|
||||
use usbd_human_interface_device::page::Keyboard;
|
||||
|
||||
// Function (Fn) buttons index (need two buttons)
|
||||
pub const FN_BUTTONS: [u8; 2] = [37, 40];
|
||||
|
||||
// Button map to HID key (three Function layers)
|
||||
pub const MAP: [[Keyboard; NUMBER_OF_KEYS]; 3] = [
|
||||
[
|
||||
// Function layer 0
|
||||
// HID Key // Button Index
|
||||
Keyboard::Tab, // 0
|
||||
Keyboard::Q, // 1
|
||||
Keyboard::W, // 2
|
||||
Keyboard::E, // 3
|
||||
Keyboard::R, // 4
|
||||
Keyboard::T, // 5
|
||||
Keyboard::Y, // 6
|
||||
Keyboard::U, // 7
|
||||
Keyboard::I, // 8
|
||||
Keyboard::O, // 9
|
||||
Keyboard::P, // 10
|
||||
Keyboard::LeftBrace, // 11 // Å
|
||||
Keyboard::LeftControl, // 12
|
||||
Keyboard::A, // 13
|
||||
Keyboard::S, // 14
|
||||
Keyboard::D, // 15
|
||||
Keyboard::F, // 16
|
||||
Keyboard::G, // 17
|
||||
Keyboard::H, // 18
|
||||
Keyboard::J, // 19
|
||||
Keyboard::K, // 20
|
||||
Keyboard::L, // 21
|
||||
Keyboard::Semicolon, // 22 // Ö
|
||||
Keyboard::Apostrophe, // 23 // Ä
|
||||
Keyboard::LeftShift, // 24
|
||||
Keyboard::Z, // 25
|
||||
Keyboard::X, // 26
|
||||
Keyboard::C, // 27
|
||||
Keyboard::V, // 28
|
||||
Keyboard::B, // 29
|
||||
Keyboard::N, // 30
|
||||
Keyboard::M, // 31
|
||||
Keyboard::Comma, // 32
|
||||
Keyboard::Dot, // 33
|
||||
Keyboard::ForwardSlash, // 34 // -
|
||||
Keyboard::RightShift, // 35
|
||||
Keyboard::LeftAlt, // 36
|
||||
Keyboard::NoEventIndicated, // 37 // Fn
|
||||
Keyboard::Space, // 38
|
||||
Keyboard::Space, // 39
|
||||
Keyboard::NoEventIndicated, // 40 // Fn
|
||||
Keyboard::RightAlt, // 41
|
||||
],
|
||||
[
|
||||
// Function layer 1
|
||||
// HID Key // Button Index
|
||||
Keyboard::Escape, // 0
|
||||
Keyboard::F1, // 1
|
||||
Keyboard::F2, // 2
|
||||
Keyboard::F3, // 3
|
||||
Keyboard::F4, // 4
|
||||
Keyboard::F5, // 5
|
||||
Keyboard::F6, // 6
|
||||
Keyboard::F7, // 7
|
||||
Keyboard::F8, // 8
|
||||
Keyboard::F9, // 9
|
||||
Keyboard::F10, // 10
|
||||
Keyboard::DeleteBackspace, // 11
|
||||
Keyboard::LeftControl, // 12
|
||||
Keyboard::Keyboard1, // 13
|
||||
Keyboard::Keyboard2, // 14
|
||||
Keyboard::Keyboard3, // 15
|
||||
Keyboard::Keyboard4, // 16
|
||||
Keyboard::Keyboard5, // 17
|
||||
Keyboard::Keyboard6, // 18
|
||||
Keyboard::Keyboard7, // 19
|
||||
Keyboard::Keyboard8, // 20
|
||||
Keyboard::Keyboard9, // 21
|
||||
Keyboard::Keyboard0, // 22
|
||||
Keyboard::ReturnEnter, // 23
|
||||
Keyboard::LeftShift, // 24
|
||||
Keyboard::Keyboard6, // 25
|
||||
Keyboard::Keyboard7, // 26
|
||||
Keyboard::Keyboard8, // 27
|
||||
Keyboard::Keyboard9, // 28
|
||||
Keyboard::Keyboard0, // 29
|
||||
Keyboard::NonUSBackslash, // 30 // <
|
||||
Keyboard::Equal, // 31 // ´
|
||||
Keyboard::Backslash, // 32 // '
|
||||
Keyboard::RightBrace, // 33 // ^
|
||||
Keyboard::Minus, // 34 // +
|
||||
Keyboard::RightShift, // 35
|
||||
Keyboard::LeftAlt, // 36
|
||||
Keyboard::NoEventIndicated, // 37 // Fn
|
||||
Keyboard::DeleteBackspace, // 38
|
||||
Keyboard::DeleteBackspace, // 39
|
||||
Keyboard::NoEventIndicated, // 40// Fn
|
||||
Keyboard::RightAlt, // 41
|
||||
],
|
||||
[
|
||||
// Function layer 2
|
||||
// HID Key // Button Index
|
||||
Keyboard::F11, // 0
|
||||
Keyboard::F12, // 1
|
||||
Keyboard::F13, // 2
|
||||
Keyboard::F14, // 3
|
||||
Keyboard::F15, // 4
|
||||
Keyboard::F16, // 5
|
||||
Keyboard::Grave, // 6 // §
|
||||
Keyboard::NoEventIndicated, // 7
|
||||
Keyboard::LeftGUI, // 8
|
||||
Keyboard::NoEventIndicated, // 9
|
||||
Keyboard::CapsLock, // 10
|
||||
Keyboard::DeleteBackspace, // 11
|
||||
Keyboard::LeftControl, // 12
|
||||
Keyboard::NoEventIndicated, // 13
|
||||
Keyboard::NoEventIndicated, // 14
|
||||
Keyboard::F17, // 15
|
||||
Keyboard::F18, // 16
|
||||
Keyboard::F19, // 17
|
||||
Keyboard::LeftArrow, // 18
|
||||
Keyboard::DownArrow, // 19
|
||||
Keyboard::UpArrow, // 20
|
||||
Keyboard::RightArrow, // 21
|
||||
Keyboard::DeleteForward, // 22
|
||||
Keyboard::ReturnEnter, // 23
|
||||
Keyboard::LeftShift, // 24
|
||||
Keyboard::F20, // 25
|
||||
Keyboard::F21, // 26
|
||||
Keyboard::F22, // 27
|
||||
Keyboard::F23, // 28
|
||||
Keyboard::F24, // 29
|
||||
Keyboard::Home, // 30
|
||||
Keyboard::PageDown, // 31
|
||||
Keyboard::PageUp, // 32
|
||||
Keyboard::End, // 33
|
||||
Keyboard::Insert, // 34
|
||||
Keyboard::RightShift, // 35
|
||||
Keyboard::LeftAlt, // 36
|
||||
Keyboard::NoEventIndicated, // 37 // Fn
|
||||
Keyboard::LeftGUI, // 38
|
||||
Keyboard::DeleteBackspace, // 39
|
||||
Keyboard::NoEventIndicated, // 40 // Fn
|
||||
Keyboard::RightAlt, // 41
|
||||
],
|
||||
];
|
||||
@ -1,6 +1,12 @@
|
||||
// TODO: Add license header
|
||||
// TODO: Add documentation header
|
||||
// TODO: GUI lock button support
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
mod layout;
|
||||
|
||||
use core::convert::Infallible;
|
||||
use cortex_m::delay::Delay;
|
||||
use embedded_hal::digital::v2::*;
|
||||
@ -31,13 +37,13 @@ pub const KEY_COLS: usize = 12;
|
||||
pub const NUMBER_OF_KEYS: usize = 42;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct MatrixKey {
|
||||
struct ButtonMatrix {
|
||||
current_state: bool,
|
||||
previous_state: bool,
|
||||
fn_mode: u8,
|
||||
}
|
||||
|
||||
impl MatrixKey {
|
||||
impl ButtonMatrix {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
current_state: false,
|
||||
@ -106,16 +112,17 @@ fn main() -> ! {
|
||||
timer.count_down(),
|
||||
);
|
||||
|
||||
let mut matrix_keys: [MatrixKey; NUMBER_OF_KEYS] = [MatrixKey::default(); NUMBER_OF_KEYS];
|
||||
let mut button_matrix: [ButtonMatrix; NUMBER_OF_KEYS] =
|
||||
[ButtonMatrix::default(); NUMBER_OF_KEYS];
|
||||
|
||||
let matrix_rows: &[&dyn InputPin<Error = Infallible>] = &[
|
||||
let button_matrix_row_pins: &[&dyn InputPin<Error = Infallible>] = &[
|
||||
&pins.gp0.into_pull_up_input(),
|
||||
&pins.gp1.into_pull_up_input(),
|
||||
&pins.gp29.into_pull_up_input(),
|
||||
&pins.gp28.into_pull_up_input(),
|
||||
];
|
||||
|
||||
let matrix_cols: &mut [&mut dyn OutputPin<Error = Infallible>] = &mut [
|
||||
let button_matrix_col_pins: &mut [&mut dyn OutputPin<Error = Infallible>] = &mut [
|
||||
&mut pins.gp12.into_push_pull_output(),
|
||||
&mut pins.gp13.into_push_pull_output(),
|
||||
&mut pins.gp14.into_push_pull_output(),
|
||||
@ -130,169 +137,16 @@ fn main() -> ! {
|
||||
&mut pins.gp11.into_push_pull_output(),
|
||||
];
|
||||
|
||||
// ------------------------------------- -------------------------------------
|
||||
// | 0 | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 10 | 11 |
|
||||
// | 12 | 13 | 14 | 15 | 16 | 17 | | 18 | 19 | 20 | 21 | 22 | 23 |
|
||||
// | 24 | 25 | 26 | 27 | 28 | 29 | | 30 | 31 | 32 | 33 | 34 | 35 |
|
||||
// ------------------| 36 | 37 | 38 | | 39 | 40 | 41 |------------------
|
||||
// ------------------- -------------------
|
||||
// GRAVE = §
|
||||
// SEMICOLON = ö
|
||||
// APOSTROPHE = ä
|
||||
// LEFT_BRACE = å
|
||||
// FORWARDSLASH = -
|
||||
// NON_US_BACKSLASH = <
|
||||
// EQUAL = ´
|
||||
// BACKSLASH = '
|
||||
// RIGHT_BRACE = ^
|
||||
// MINUS = +
|
||||
// LEFT_ALT = Alt
|
||||
// RIGHT_ALT = AltGr
|
||||
|
||||
let layout: [[Keyboard; NUMBER_OF_KEYS]; 3] = [
|
||||
[
|
||||
// Function layer 0
|
||||
Keyboard::Tab,
|
||||
Keyboard::Q,
|
||||
Keyboard::W,
|
||||
Keyboard::E,
|
||||
Keyboard::R,
|
||||
Keyboard::T,
|
||||
Keyboard::Y,
|
||||
Keyboard::U,
|
||||
Keyboard::I,
|
||||
Keyboard::O,
|
||||
Keyboard::P,
|
||||
Keyboard::LeftBrace,
|
||||
Keyboard::LeftControl,
|
||||
Keyboard::A,
|
||||
Keyboard::S,
|
||||
Keyboard::D,
|
||||
Keyboard::F,
|
||||
Keyboard::G,
|
||||
Keyboard::H,
|
||||
Keyboard::J,
|
||||
Keyboard::K,
|
||||
Keyboard::L,
|
||||
Keyboard::Semicolon,
|
||||
Keyboard::Apostrophe,
|
||||
Keyboard::LeftShift,
|
||||
Keyboard::Z,
|
||||
Keyboard::X,
|
||||
Keyboard::C,
|
||||
Keyboard::V,
|
||||
Keyboard::B,
|
||||
Keyboard::N,
|
||||
Keyboard::M,
|
||||
Keyboard::Comma,
|
||||
Keyboard::Dot,
|
||||
Keyboard::ForwardSlash,
|
||||
Keyboard::RightShift,
|
||||
Keyboard::LeftAlt,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::Space,
|
||||
Keyboard::Space,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::RightAlt,
|
||||
],
|
||||
[
|
||||
// Function layer 1
|
||||
Keyboard::Escape,
|
||||
Keyboard::F1,
|
||||
Keyboard::F2,
|
||||
Keyboard::F3,
|
||||
Keyboard::F4,
|
||||
Keyboard::F5,
|
||||
Keyboard::F6,
|
||||
Keyboard::F7,
|
||||
Keyboard::F8,
|
||||
Keyboard::F9,
|
||||
Keyboard::F10,
|
||||
Keyboard::DeleteBackspace,
|
||||
Keyboard::LeftControl,
|
||||
Keyboard::Keyboard1,
|
||||
Keyboard::Keyboard2,
|
||||
Keyboard::Keyboard3,
|
||||
Keyboard::Keyboard4,
|
||||
Keyboard::Keyboard5,
|
||||
Keyboard::Keyboard6,
|
||||
Keyboard::Keyboard7,
|
||||
Keyboard::Keyboard8,
|
||||
Keyboard::Keyboard9,
|
||||
Keyboard::Keyboard0,
|
||||
Keyboard::ReturnEnter,
|
||||
Keyboard::LeftShift,
|
||||
Keyboard::Keyboard6,
|
||||
Keyboard::Keyboard7,
|
||||
Keyboard::Keyboard8,
|
||||
Keyboard::Keyboard9,
|
||||
Keyboard::Keyboard0,
|
||||
Keyboard::NonUSBackslash,
|
||||
Keyboard::Equal,
|
||||
Keyboard::Backslash,
|
||||
Keyboard::RightBrace,
|
||||
Keyboard::Minus,
|
||||
Keyboard::RightShift,
|
||||
Keyboard::LeftAlt,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::DeleteBackspace,
|
||||
Keyboard::DeleteBackspace,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::RightAlt,
|
||||
],
|
||||
[
|
||||
// Function layer 2
|
||||
Keyboard::F11,
|
||||
Keyboard::F12,
|
||||
Keyboard::F13,
|
||||
Keyboard::F14,
|
||||
Keyboard::F15,
|
||||
Keyboard::F16,
|
||||
Keyboard::Grave,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::LeftGUI,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::CapsLock,
|
||||
Keyboard::DeleteBackspace,
|
||||
Keyboard::LeftControl,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::F17,
|
||||
Keyboard::F18,
|
||||
Keyboard::F19,
|
||||
Keyboard::LeftArrow,
|
||||
Keyboard::DownArrow,
|
||||
Keyboard::UpArrow,
|
||||
Keyboard::RightArrow,
|
||||
Keyboard::DeleteForward,
|
||||
Keyboard::ReturnEnter,
|
||||
Keyboard::LeftShift,
|
||||
Keyboard::F20,
|
||||
Keyboard::F21,
|
||||
Keyboard::F22,
|
||||
Keyboard::F23,
|
||||
Keyboard::F24,
|
||||
Keyboard::Home,
|
||||
Keyboard::PageDown,
|
||||
Keyboard::PageUp,
|
||||
Keyboard::End,
|
||||
Keyboard::Insert,
|
||||
Keyboard::RightShift,
|
||||
Keyboard::LeftAlt,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::LeftGUI,
|
||||
Keyboard::DeleteBackspace,
|
||||
Keyboard::NoEventIndicated,
|
||||
Keyboard::RightAlt,
|
||||
],
|
||||
];
|
||||
|
||||
let mut input_count_down = timer.count_down();
|
||||
input_count_down.start(10.millis());
|
||||
let mut report_count_down = timer.count_down();
|
||||
report_count_down.start(10.millis());
|
||||
|
||||
let mut tick_count_down = timer.count_down();
|
||||
tick_count_down.start(1.millis());
|
||||
|
||||
let mut indicator_count_down = timer.count_down();
|
||||
indicator_count_down.start(250.millis());
|
||||
|
||||
let mut status_led_onoff: bool = false;
|
||||
let status_led_color: [RGB8; 5] = [
|
||||
(0, 0, 0).into(), // Off
|
||||
(10, 7, 0).into(), // Green
|
||||
@ -301,38 +155,52 @@ fn main() -> ! {
|
||||
(2, 20, 0).into(), // Red
|
||||
];
|
||||
|
||||
let mut caps_lock_active = false;
|
||||
let mut caps_lock_active: bool = false;
|
||||
let mut fn_mode: u8 = 0;
|
||||
|
||||
init_keyboard_matrix_pins(matrix_cols, &mut delay);
|
||||
// Set all column pins to output and high
|
||||
init_button_matrix_pins(button_matrix_col_pins, &mut delay);
|
||||
|
||||
// Infinite colour wheel loop
|
||||
loop {
|
||||
if input_count_down.wait().is_ok() {
|
||||
// Scan keyboard matrix
|
||||
let pressed_keys = get_pressed_keys(matrix_rows, matrix_cols, &mut delay);
|
||||
|
||||
// Get current function layer
|
||||
let fn_mode = get_fn_mode(pressed_keys);
|
||||
|
||||
if indicator_count_down.wait().is_ok() {
|
||||
// Set status LED colour based on function layer and capslock
|
||||
// 0 = green, 1 = blue, 2 = orange, capslock active = red.
|
||||
if caps_lock_active == true {
|
||||
// 0 = green, 1 = blue, 2 = orange, capslock active = flashing.
|
||||
if caps_lock_active == true && status_led_onoff == true {
|
||||
status_led
|
||||
.write([status_led_color[4]].iter().copied())
|
||||
.write([status_led_color[0]].iter().copied())
|
||||
.unwrap();
|
||||
status_led_onoff = false;
|
||||
} else {
|
||||
status_led
|
||||
.write([status_led_color[usize::from(fn_mode) + 1]].iter().copied())
|
||||
.unwrap();
|
||||
status_led_onoff = true;
|
||||
}
|
||||
}
|
||||
|
||||
if report_count_down.wait().is_ok() {
|
||||
// Scan keyboard matrix
|
||||
let pressed_keys =
|
||||
get_pressed_buttons(button_matrix_row_pins, button_matrix_col_pins, &mut delay);
|
||||
|
||||
// Get current function layer
|
||||
fn_mode = get_fn_mode(pressed_keys);
|
||||
|
||||
// Set status LED colour based on function layer and capslock
|
||||
// 0 = green, 1 = blue, 2 = orange, capslock active = flashing.
|
||||
if caps_lock_active == false {
|
||||
status_led
|
||||
.write([status_led_color[usize::from(fn_mode) + 1]].iter().copied())
|
||||
.unwrap();
|
||||
status_led_onoff = true;
|
||||
}
|
||||
// Copy result from scanned keys to matrix struct
|
||||
for (index, key) in pressed_keys.iter().enumerate() {
|
||||
matrix_keys[index].current_state = *key;
|
||||
button_matrix[index].current_state = *key;
|
||||
}
|
||||
|
||||
// Generate keyboard report
|
||||
let keyboard_report = get_keyboard_report(matrix_keys, layout, fn_mode);
|
||||
let keyboard_report = get_keyboard_report(&mut button_matrix, layout::MAP, fn_mode);
|
||||
|
||||
match keyboard.device().write_report(keyboard_report) {
|
||||
Err(UsbHidError::WouldBlock) => {}
|
||||
@ -376,10 +244,7 @@ fn main() -> ! {
|
||||
}
|
||||
|
||||
// Initialise keyboard matrix pins
|
||||
fn init_keyboard_matrix_pins(
|
||||
cols: &mut [&mut dyn OutputPin<Error = Infallible>],
|
||||
delay: &mut Delay,
|
||||
) {
|
||||
fn init_button_matrix_pins(cols: &mut [&mut dyn OutputPin<Error = Infallible>], delay: &mut Delay) {
|
||||
for col in cols.iter_mut() {
|
||||
col.set_high().unwrap();
|
||||
}
|
||||
@ -389,7 +254,7 @@ fn init_keyboard_matrix_pins(
|
||||
// Scan keyboard matrix for pressed keys and return a bool array
|
||||
// representing the state of each key (true = pressed)
|
||||
// TODO: This is a bit of a mess, needs refactoring
|
||||
fn get_pressed_keys(
|
||||
fn get_pressed_buttons(
|
||||
rows: &[&dyn InputPin<Error = Infallible>],
|
||||
cols: &mut [&mut dyn OutputPin<Error = Infallible>],
|
||||
delay: &mut Delay,
|
||||
@ -425,18 +290,18 @@ fn get_pressed_keys(
|
||||
fn get_fn_mode(pressed_keys: [bool; NUMBER_OF_KEYS]) -> u8 {
|
||||
// Check Fn mode
|
||||
let mut fn_mode: u8 = 0;
|
||||
if pressed_keys[37] == true && pressed_keys[40] == true {
|
||||
fn_mode = 2;
|
||||
} else if pressed_keys[37] == true || pressed_keys[40] == true {
|
||||
fn_mode = 1;
|
||||
for button_id in layout::FN_BUTTONS.iter() {
|
||||
if pressed_keys[usize::from(*button_id)] == true {
|
||||
fn_mode += 1;
|
||||
}
|
||||
}
|
||||
fn_mode
|
||||
}
|
||||
|
||||
// Generate keyboard report based on pressed keys and Fn mode (0, 1 or 2)
|
||||
fn get_keyboard_report(
|
||||
mut matrix_keys: [MatrixKey; NUMBER_OF_KEYS],
|
||||
layout: [[Keyboard; NUMBER_OF_KEYS]; 3],
|
||||
matrix_keys: &mut [ButtonMatrix; NUMBER_OF_KEYS],
|
||||
layout_map: [[Keyboard; NUMBER_OF_KEYS]; 3],
|
||||
fn_mode: u8,
|
||||
) -> [Keyboard; NUMBER_OF_KEYS] {
|
||||
// Create default report
|
||||
@ -445,11 +310,12 @@ fn get_keyboard_report(
|
||||
// Filter report based on Fn mode and pressed keys
|
||||
for (index, key) in matrix_keys.iter_mut().enumerate() {
|
||||
if key.current_state != key.previous_state && key.current_state == true {
|
||||
key.previous_state = key.current_state;
|
||||
key.fn_mode = fn_mode;
|
||||
}
|
||||
key.previous_state = key.current_state;
|
||||
|
||||
if key.current_state == true {
|
||||
keyboard_report[index] = layout[usize::from(key.fn_mode)][index];
|
||||
keyboard_report[index] = layout_map[usize::from(key.fn_mode)][index];
|
||||
}
|
||||
}
|
||||
// Return report
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user