First attemt on runnable code

This commit is contained in:
Christoffer Martinsson 2023-06-18 20:21:58 +02:00
parent 9d683b8850
commit 63aefa717f

View File

@ -2,6 +2,7 @@
#![no_main]
use core::convert::Infallible;
use cortex_m::delay::Delay;
use embedded_hal::digital::v2::*;
use embedded_hal::timer::CountDown;
use fugit::ExtU32;
@ -25,10 +26,29 @@ use waveshare_rp2040_zero::{
};
use ws2812_pio::Ws2812;
pub const NUMBER_OF_KEYS: usize = 42;
#[derive(Copy, Clone)]
struct MatrixKey {
current_state: bool,
previous_state: bool,
fn_mode: u8,
}
impl MatrixKey {
fn default() -> Self {
Self {
current_state: false,
previous_state: false,
fn_mode: 0,
}
}
}
#[entry]
fn main() -> ! {
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let clocks = init_clocks_and_plls(
@ -72,11 +92,11 @@ fn main() -> ! {
.build();
let timer = Timer::new(pac.TIMER, &mut pac.RESETS);
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
// Configure the addressable LED
// Configure the status LED
let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS);
let mut ws = Ws2812::new(
// The onboard NeoPixel is attached to GPIO pin #16 on the Feather RP2040.
let mut status_led = Ws2812::new(
pins.neopixel.into_mode(),
&mut pio,
sm0,
@ -84,26 +104,182 @@ fn main() -> ! {
timer.count_down(),
);
let matrix_rows: &[&dyn InputPin<Error = core::convert::Infallible>] = &[
let mut matrix_keys: [MatrixKey; NUMBER_OF_KEYS] = [MatrixKey::default(); NUMBER_OF_KEYS];
let matrix_rows: &[&dyn InputPin<Error = Infallible>] = &[
&pins.gp0.into_pull_up_input(),
&pins.gp1.into_pull_up_input(),
&pins.gp2.into_pull_up_input(),
&pins.gp3.into_pull_up_input(),
&pins.gp29.into_pull_up_input(),
&pins.gp28.into_pull_up_input(),
];
let matrix_cols: &[&dyn OutputPin<Error = core::convert::Infallible>] = &[
&pins.gp4.into_push_pull_output(),
&pins.gp5.into_push_pull_output(),
&pins.gp6.into_push_pull_output(),
&pins.gp7.into_push_pull_output(),
&pins.gp8.into_push_pull_output(),
&pins.gp9.into_push_pull_output(),
&pins.gp10.into_push_pull_output(),
&pins.gp11.into_push_pull_output(),
&pins.gp12.into_push_pull_output(),
&pins.gp13.into_push_pull_output(),
&pins.gp14.into_push_pull_output(),
&pins.gp15.into_push_pull_output(),
let matrix_cols: &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(),
&mut pins.gp15.into_push_pull_output(),
&mut pins.gp26.into_push_pull_output(),
&mut pins.gp27.into_push_pull_output(),
&mut pins.gp7.into_push_pull_output(),
&mut pins.gp8.into_push_pull_output(),
&mut pins.gp6.into_push_pull_output(),
&mut pins.gp9.into_push_pull_output(),
&mut pins.gp10.into_push_pull_output(),
&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();
@ -114,19 +290,34 @@ fn main() -> ! {
let color_purple: RGB8 = (0, 10, 10).into();
let color_red: RGB8 = (0, 10, 0).into();
// let color_green: RGB8 = (10, 0, 0).into();
// let color_blue: RGB8 = (0, 0, 10).into();
let color_none: RGB8 = (0, 0, 0).into();
init_keyboard_matrix_pins(matrix_cols, &mut delay);
// Infinite colour wheel loop
loop {
if input_count_down.wait().is_ok() {
match keyboard.device().write_report([Keyboard::NoEventIndicated; 12]) {
// 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);
// Copy result from scanned keys to matrix struct
for (index, key) in pressed_keys.iter().enumerate() {
matrix_keys[index].current_state = *key;
}
// Generate keyboard report
let keyboard_report =
get_keyboard_report(matrix_keys, layout, fn_mode);
match keyboard.device().write_report(keyboard_report) {
Err(UsbHidError::WouldBlock) => {}
Err(UsbHidError::Duplicate) => {}
Ok(_) => {}
Err(e) => {
ws.write([color_red].iter().copied()).unwrap();
status_led.write([color_red].iter().copied()).unwrap();
core::panic!("Failed to write keyboard report: {:?}", e)
}
};
@ -138,7 +329,7 @@ fn main() -> ! {
Err(UsbHidError::WouldBlock) => {}
Ok(_) => {}
Err(e) => {
ws.write([color_red].iter().copied()).unwrap();
status_led.write([color_red].iter().copied()).unwrap();
core::panic!("Failed to process keyboard tick: {:?}", e)
}
};
@ -150,17 +341,99 @@ fn main() -> ! {
//do nothing
}
Err(e) => {
ws.write([color_red].iter().copied()).unwrap();
status_led.write([color_red].iter().copied()).unwrap();
core::panic!("Failed to read keyboard report: {:?}", e)
}
Ok(leds) => {
if leds.caps_lock == true {
ws.write([color_purple].iter().copied()).unwrap();
status_led.write([color_purple].iter().copied()).unwrap();
} else {
ws.write([color_none].iter().copied()).unwrap();
status_led.write([color_none].iter().copied()).unwrap();
}
}
}
}
}
}
// Initialise keyboard matrix pins
fn init_keyboard_matrix_pins(
cols: &mut [&mut dyn OutputPin<Error = Infallible>],
delay: &mut Delay,
) {
for col in cols.iter_mut() {
col.set_high().unwrap();
}
delay.delay_us(10);
}
// 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(
rows: &[&dyn InputPin<Error = Infallible>],
cols: &mut [&mut dyn OutputPin<Error = Infallible>],
delay: &mut Delay,
) -> [bool; NUMBER_OF_KEYS] {
// Scan keyboard matrix for pressed keys
let mut pressed_keys: [bool; NUMBER_OF_KEYS] = [false; NUMBER_OF_KEYS];
let mut key_index: usize = 0;
for (col_index, col) in cols.iter_mut().enumerate() {
col.set_low().unwrap();
delay.delay_us(10);
for (row_index, row) in rows.iter().enumerate() {
if col_index == 3
&& (row_index == 0
|| row_index == 1
|| row_index == 2
|| row_index == 9
|| row_index == 10
|| row_index == 11)
{
continue;
}
if row.is_low().unwrap() {
pressed_keys[key_index] = true;
}
key_index += 1;
}
col.set_high().unwrap();
delay.delay_us(10);
}
// Return scan result
pressed_keys
}
// Get current Fn mode (0, 1 or 2)
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;
}
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],
fn_mode: u8,
) -> [Keyboard; NUMBER_OF_KEYS] {
// Create default report
let mut keyboard_report: [Keyboard; NUMBER_OF_KEYS] =
[Keyboard::NoEventIndicated; NUMBER_OF_KEYS];
// 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.fn_mode = fn_mode;
}
if key.current_state == true {
keyboard_report[index] = layout[index][usize::from(key.fn_mode)];
}
}
// Return report
keyboard_report
}