
6 changed files with 668 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||
/firmware/target |
|||
**/*.rs.bk |
|||
*~ |
|||
*.bin |
@ -0,0 +1,12 @@ |
|||
[target.thumbv6m-none-eabi] |
|||
|
|||
# uncomment ONE of these three option to make `cargo run` start a GDB session |
|||
# which option to pick depends on your system |
|||
runner = "arm-none-eabi-gdb -q -x openocd.gdb" |
|||
# runner = "gdb-multiarch -q -x openocd.gdb" |
|||
# runner = "gdb -q -x openocd.gdb" |
|||
|
|||
rustflags = ["-C", "link-arg=-Tlink.x"] |
|||
|
|||
[build] |
|||
target = "thumbv6m-none-eabi" |
@ -0,0 +1,411 @@ |
|||
# This file is automatically @generated by Cargo. |
|||
# It is not intended for manual editing. |
|||
[[package]] |
|||
name = "aligned" |
|||
version = "0.3.4" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "c19796bd8d477f1a9d4ac2465b464a8b1359474f06a96bb3cda650b4fca309bf" |
|||
dependencies = [ |
|||
"as-slice", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "arraydeque" |
|||
version = "0.4.5" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "f0ffd3d69bd89910509a5d31d1f1353f38ccffdd116dd0099bbd6627f7bd8ad8" |
|||
|
|||
[[package]] |
|||
name = "as-slice" |
|||
version = "0.1.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70" |
|||
dependencies = [ |
|||
"generic-array 0.12.3", |
|||
"generic-array 0.13.2", |
|||
"stable_deref_trait", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "autocfg" |
|||
version = "1.0.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" |
|||
|
|||
[[package]] |
|||
name = "bare-metal" |
|||
version = "0.2.5" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" |
|||
dependencies = [ |
|||
"rustc_version", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "bitfield" |
|||
version = "0.13.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" |
|||
|
|||
[[package]] |
|||
name = "byteorder" |
|||
version = "1.3.4" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" |
|||
|
|||
[[package]] |
|||
name = "cast" |
|||
version = "0.2.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" |
|||
dependencies = [ |
|||
"rustc_version", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "cortex-m" |
|||
version = "0.6.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "2be99930c99669a74d986f7fd2162085498b322e6daae8ef63a97cc9ac1dc73c" |
|||
dependencies = [ |
|||
"aligned", |
|||
"bare-metal", |
|||
"bitfield", |
|||
"volatile-register", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "cortex-m-rt" |
|||
version = "0.6.12" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "00d518da72bba39496024b62607c1d8e37bcece44b2536664f1132a73a499a28" |
|||
dependencies = [ |
|||
"cortex-m-rt-macros", |
|||
"r0", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "cortex-m-rt-macros" |
|||
version = "0.1.8" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "4717562afbba06e760d34451919f5c3bf3ac15c7bb897e8b04862a7428378647" |
|||
dependencies = [ |
|||
"proc-macro2", |
|||
"quote", |
|||
"syn", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "cortex-m-rtfm" |
|||
version = "0.5.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "4fc65a600a5c8baf0a5fd3b2c0223b8d8fc7aa7d6d0c9a3350ce40a4da49ccea" |
|||
dependencies = [ |
|||
"cortex-m", |
|||
"cortex-m-rt", |
|||
"cortex-m-rtfm-macros", |
|||
"heapless", |
|||
"rtfm-core", |
|||
"version_check", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "cortex-m-rtfm-macros" |
|||
version = "0.5.1" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "fa4a3fc88fff9970152a7f79bf6919d538395bc1f11ba90a1e6970a3521d8b88" |
|||
dependencies = [ |
|||
"proc-macro2", |
|||
"quote", |
|||
"rtfm-syntax", |
|||
"syn", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "either" |
|||
version = "1.5.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" |
|||
|
|||
[[package]] |
|||
name = "embedded-hal" |
|||
version = "0.2.4" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "fa998ce59ec9765d15216393af37a58961ddcefb14c753b4816ba2191d865fcb" |
|||
dependencies = [ |
|||
"nb 0.1.3", |
|||
"void", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "generic-array" |
|||
version = "0.12.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" |
|||
dependencies = [ |
|||
"typenum", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "generic-array" |
|||
version = "0.13.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" |
|||
dependencies = [ |
|||
"typenum", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "hash32" |
|||
version = "0.1.1" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc" |
|||
dependencies = [ |
|||
"byteorder", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "hashbrown" |
|||
version = "0.8.1" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" |
|||
dependencies = [ |
|||
"autocfg", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "heapless" |
|||
version = "0.5.5" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "73a8a2391a3bc70b31f60e7a90daa5755a360559c0b6b9c5cfc0fee482362dc0" |
|||
dependencies = [ |
|||
"as-slice", |
|||
"generic-array 0.13.2", |
|||
"hash32", |
|||
"stable_deref_trait", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "indexmap" |
|||
version = "1.5.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" |
|||
dependencies = [ |
|||
"autocfg", |
|||
"hashbrown", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "keyberon" |
|||
version = "0.1.0" |
|||
source = "git+https://github.com/TeXitoi/keyberon#1d5ddd00785ea612fe4beccbe2abb4097842facb" |
|||
dependencies = [ |
|||
"arraydeque", |
|||
"either", |
|||
"embedded-hal", |
|||
"generic-array 0.13.2", |
|||
"heapless", |
|||
"usb-device", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "keyberon-f4" |
|||
version = "0.1.0" |
|||
dependencies = [ |
|||
"cortex-m", |
|||
"cortex-m-rt", |
|||
"cortex-m-rtfm", |
|||
"embedded-hal", |
|||
"generic-array 0.13.2", |
|||
"keyberon", |
|||
"panic-halt", |
|||
"stm32f0xx-hal", |
|||
"usb-device", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "nb" |
|||
version = "0.1.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" |
|||
dependencies = [ |
|||
"nb 1.0.0", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "nb" |
|||
version = "1.0.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" |
|||
|
|||
[[package]] |
|||
name = "panic-halt" |
|||
version = "0.2.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" |
|||
|
|||
[[package]] |
|||
name = "proc-macro2" |
|||
version = "1.0.19" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" |
|||
dependencies = [ |
|||
"unicode-xid", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "quote" |
|||
version = "1.0.7" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" |
|||
dependencies = [ |
|||
"proc-macro2", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "r0" |
|||
version = "0.2.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" |
|||
|
|||
[[package]] |
|||
name = "rtfm-core" |
|||
version = "0.3.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "9ec893edb2aa5b70320b94896ffea22a7ebb1cf3f942bb67cd5b60a865a63493" |
|||
|
|||
[[package]] |
|||
name = "rtfm-syntax" |
|||
version = "0.4.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "4455e23c34df3d66454e7e218a4d76a7f83321d04a806be614463341cec4116e" |
|||
dependencies = [ |
|||
"indexmap", |
|||
"proc-macro2", |
|||
"syn", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "rustc_version" |
|||
version = "0.2.3" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" |
|||
dependencies = [ |
|||
"semver", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "semver" |
|||
version = "0.9.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" |
|||
dependencies = [ |
|||
"semver-parser", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "semver-parser" |
|||
version = "0.7.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" |
|||
|
|||
[[package]] |
|||
name = "stable_deref_trait" |
|||
version = "1.2.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" |
|||
|
|||
[[package]] |
|||
name = "stm32-usbd" |
|||
version = "0.5.1" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "70d13eca735cae37df697f599777b000cc0ee924df8452f2b4bfaa6798ab0338" |
|||
dependencies = [ |
|||
"cortex-m", |
|||
"usb-device", |
|||
"vcell", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "stm32f0" |
|||
version = "0.11.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "9673b9c3ecdf8ea1133492f3070515d64f51e98439710eae062552fc80b94a6c" |
|||
dependencies = [ |
|||
"bare-metal", |
|||
"cortex-m", |
|||
"cortex-m-rt", |
|||
"vcell", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "stm32f0xx-hal" |
|||
version = "0.17.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "212a649a93c47b422e05dfab72dd45ef24b226d826654f393caeef729e110582" |
|||
dependencies = [ |
|||
"bare-metal", |
|||
"cast", |
|||
"cortex-m", |
|||
"embedded-hal", |
|||
"nb 0.1.3", |
|||
"stm32-usbd", |
|||
"stm32f0", |
|||
"void", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "syn" |
|||
version = "1.0.36" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250" |
|||
dependencies = [ |
|||
"proc-macro2", |
|||
"quote", |
|||
"unicode-xid", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "typenum" |
|||
version = "1.12.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" |
|||
|
|||
[[package]] |
|||
name = "unicode-xid" |
|||
version = "0.2.1" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" |
|||
|
|||
[[package]] |
|||
name = "usb-device" |
|||
version = "0.2.5" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "0e5e2b9ba23f0d9ef7a34e498b6581c9d67944a1916542bfc7238bf1dc0d6acd" |
|||
|
|||
[[package]] |
|||
name = "vcell" |
|||
version = "0.1.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" |
|||
|
|||
[[package]] |
|||
name = "version_check" |
|||
version = "0.9.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" |
|||
|
|||
[[package]] |
|||
name = "void" |
|||
version = "1.0.2" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" |
|||
|
|||
[[package]] |
|||
name = "volatile-register" |
|||
version = "0.2.0" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" |
|||
dependencies = [ |
|||
"vcell", |
|||
] |
@ -0,0 +1,22 @@ |
|||
[package] |
|||
name = "keyberon-f4" |
|||
version = "0.1.0" |
|||
authors = ["Guillaume Pinot <texitoi@texitoi.eu>"] |
|||
edition = "2018" |
|||
|
|||
[dependencies] |
|||
stm32f0xx-hal = { version = "0.17.0", features = ["rt", "stm32f072", "stm32-usbd"] } |
|||
cortex-m = "0.6" |
|||
cortex-m-rt = { version = "0.6.10", features = ["device"] } |
|||
panic-halt = "0.2.0" |
|||
keyberon = { git = "https://github.com/TeXitoi/keyberon" } |
|||
cortex-m-rtfm = "0.5" |
|||
generic-array = "0.13" |
|||
embedded-hal = "0.2" |
|||
usb-device = "0.2.0" |
|||
|
|||
[profile.release] |
|||
lto = true |
|||
incremental = false |
|||
opt-level = "z" |
|||
debug = true |
@ -0,0 +1,6 @@ |
|||
/* Linker script for the STM32F103C8T6 */ |
|||
MEMORY |
|||
{ |
|||
FLASH : ORIGIN = 0x08000000, LENGTH = 128K |
|||
RAM : ORIGIN = 0x20000000, LENGTH = 16K |
|||
} |
@ -0,0 +1,213 @@ |
|||
#![no_main] |
|||
#![no_std] |
|||
|
|||
// set the panic handler
|
|||
use panic_halt as _; |
|||
|
|||
use core::convert::Infallible; |
|||
use embedded_hal::digital::v2::{InputPin, OutputPin}; |
|||
use generic_array::typenum::{U4, U6}; |
|||
use keyberon::action::{k, l, m, Action, Action::*}; |
|||
use keyberon::debounce::Debouncer; |
|||
use keyberon::impl_heterogenous_array; |
|||
use keyberon::key_code::KbHidReport; |
|||
use keyberon::key_code::KeyCode::{self, *}; |
|||
use keyberon::layout::Layout; |
|||
use keyberon::matrix::{Matrix, PressedKeys}; |
|||
use rtfm::app; |
|||
use stm32f0xx_hal::gpio::{gpioa, gpiob, Input, Output, PullUp, PushPull}; |
|||
use stm32f0xx_hal::prelude::*; |
|||
use stm32f0xx_hal::usb; |
|||
use stm32f0xx_hal::{stm32, timers}; |
|||
use usb_device::bus::UsbBusAllocator; |
|||
use usb_device::class::UsbClass as _; |
|||
|
|||
type UsbClass = keyberon::Class<'static, usb::UsbBusType, ()>; |
|||
type UsbDevice = keyberon::Device<'static, usb::UsbBusType>; |
|||
|
|||
pub struct Cols( |
|||
gpioa::PA15<Input<PullUp>>, |
|||
gpiob::PB3<Input<PullUp>>, |
|||
gpiob::PB4<Input<PullUp>>, |
|||
gpiob::PB5<Input<PullUp>>, |
|||
gpiob::PB8<Input<PullUp>>, |
|||
gpiob::PB9<Input<PullUp>>, |
|||
); |
|||
impl_heterogenous_array! { |
|||
Cols, |
|||
dyn InputPin<Error = Infallible>, |
|||
U6, |
|||
[0, 1, 2, 3, 4, 5] |
|||
} |
|||
|
|||
pub struct Rows( |
|||
gpiob::PB0<Output<PushPull>>, |
|||
gpiob::PB1<Output<PushPull>>, |
|||
gpiob::PB2<Output<PushPull>>, |
|||
gpiob::PB10<Output<PushPull>>, |
|||
); |
|||
impl_heterogenous_array! { |
|||
Rows, |
|||
dyn OutputPin<Error = Infallible>, |
|||
U4, |
|||
[0, 1, 2, 3] |
|||
} |
|||
|
|||
const CUT: Action = m(&[LShift, Delete]); |
|||
const COPY: Action = m(&[LCtrl, Insert]); |
|||
const PASTE: Action = m(&[LShift, Insert]); |
|||
const L2_ENTER: Action = HoldTap { |
|||
timeout: 200, |
|||
hold: &l(2), |
|||
tap: &k(Enter), |
|||
}; |
|||
const L1_SP: Action = HoldTap { |
|||
timeout: 200, |
|||
hold: &l(1), |
|||
tap: &k(Space), |
|||
}; |
|||
const CSPACE: Action = m(&[LCtrl, Space]); |
|||
macro_rules! s { |
|||
($k:ident) => { |
|||
m(&[LShift, $k]) |
|||
}; |
|||
} |
|||
macro_rules! a { |
|||
($k:ident) => { |
|||
m(&[RAlt, $k]) |
|||
}; |
|||
} |
|||
|
|||
// The 13th column is the hardware button of the development board,
|
|||
// thus all the column is activated when the button is pushed. Because
|
|||
// of that, only one action is defined in the 13th column.
|
|||
#[rustfmt::skip] |
|||
pub static LAYERS: keyberon::layout::Layers = &[ |
|||
&[ |
|||
&[k(Tab), k(Q), k(W), k(E), k(R), k(T), k(Y), k(U), k(I), k(O), k(P), k(LBracket)], |
|||
&[k(RBracket),k(A), k(S), k(D), k(F), k(G), k(H), k(J), k(K), k(L), k(SColon),k(Quote) ], |
|||
&[k(Equal), k(Z), k(X), k(C), k(V), k(B), k(N), k(M), k(Comma),k(Dot), k(Slash), k(Bslash) ], |
|||
&[Trans, Trans,k(LGui),k(LAlt),L1_SP,k(LCtrl),k(RShift),L2_ENTER,k(RAlt),k(BSpace),Trans, Trans ], |
|||
], &[ |
|||
&[Trans, k(Pause),Trans, k(PScreen),Trans, Trans,Trans, Trans, k(Delete),Trans, Trans, Trans ], |
|||
&[Trans, Trans, k(NumLock),k(Insert), k(Escape),Trans,k(CapsLock),k(Left),k(Down), k(Up), k(Right),Trans ], |
|||
&[k(NonUsBslash),k(Undo), CUT, COPY, PASTE, Trans,Trans, k(Home),k(PgDown),k(PgUp),k(End), Trans ], |
|||
&[Trans, Trans, Trans, Trans, Trans, Trans,Trans, Trans, Trans, Trans, Trans, Trans ], |
|||
], &[ |
|||
&[s!(Grave),s!(Kb1),s!(Kb2),s!(Kb3),s!(Kb4),s!(Kb5),s!(Kb6),s!(Kb7),s!(Kb8),s!(Kb9),s!(Kb0),s!(Minus)], |
|||
&[ k(Grave), k(Kb1), k(Kb2), k(Kb3), k(Kb4), k(Kb5), k(Kb6), k(Kb7), k(Kb8), k(Kb9), k(Kb0), k(Minus)], |
|||
&[a!(Grave),a!(Kb1),a!(Kb2),a!(Kb3),a!(Kb4),a!(Kb5),a!(Kb6),a!(Kb7),a!(Kb8),a!(Kb9),a!(Kb0),a!(Minus)], |
|||
&[Trans, Trans, Trans, Trans, CSPACE, Trans, Trans, Trans, Trans, Trans, Trans, Trans ], |
|||
], &[ |
|||
&[k(F1),k(F2),k(F3),k(F4),k(F5),k(F6),k(F7),k(F8),k(F9),k(F10),k(F11),k(F12)], |
|||
&[Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans, Trans, Trans ], |
|||
&[Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans, Trans, Trans ], |
|||
&[Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans,Trans, Trans, Trans ], |
|||
], |
|||
]; |
|||
|
|||
#[app(device = stm32f0xx_hal::stm32, peripherals = true)] |
|||
const APP: () = { |
|||
struct Resources { |
|||
usb_dev: UsbDevice, |
|||
usb_class: UsbClass, |
|||
matrix: Matrix<Cols, Rows>, |
|||
debouncer: Debouncer<PressedKeys<U4, U6>>, |
|||
layout: Layout, |
|||
timer: timers::Timer<stm32::TIM3>, |
|||
} |
|||
|
|||
#[init] |
|||
fn init(mut c: init::Context) -> init::LateResources { |
|||
static mut USB_BUS: Option<UsbBusAllocator<usb::UsbBusType>> = None; |
|||
|
|||
let mut rcc = c |
|||
.device |
|||
.RCC |
|||
.configure() |
|||
.hsi48() |
|||
.enable_crs(c.device.CRS) |
|||
.sysclk(48.mhz()) |
|||
.pclk(24.mhz()) |
|||
.freeze(&mut c.device.FLASH); |
|||
|
|||
let gpioa = c.device.GPIOA.split(&mut rcc); |
|||
let gpiob = c.device.GPIOB.split(&mut rcc); |
|||
|
|||
let usb = usb::Peripheral { |
|||
usb: c.device.USB, |
|||
pin_dm: gpioa.pa11, |
|||
pin_dp: gpioa.pa12, |
|||
}; |
|||
*USB_BUS = Some(usb::UsbBusType::new(usb)); |
|||
let usb_bus = USB_BUS.as_ref().unwrap(); |
|||
|
|||
let usb_class = keyberon::new_class(usb_bus, ()); |
|||
let usb_dev = keyberon::new_device(usb_bus); |
|||
|
|||
let mut timer = timers::Timer::tim3(c.device.TIM3, 1.khz(), &mut rcc); |
|||
timer.listen(timers::Event::TimeOut); |
|||
|
|||
let pa15 = gpioa.pa15; |
|||
let matrix = cortex_m::interrupt::free(move |cs| { |
|||
Matrix::new( |
|||
Cols( |
|||
pa15.into_pull_up_input(cs), |
|||
gpiob.pb3.into_pull_up_input(cs), |
|||
gpiob.pb4.into_pull_up_input(cs), |
|||
gpiob.pb5.into_pull_up_input(cs), |
|||
gpiob.pb8.into_pull_up_input(cs), |
|||
gpiob.pb9.into_pull_up_input(cs), |
|||
), |
|||
Rows( |
|||
gpiob.pb0.into_push_pull_output(cs), |
|||
gpiob.pb1.into_push_pull_output(cs), |
|||
gpiob.pb2.into_push_pull_output(cs), |
|||
gpiob.pb10.into_push_pull_output(cs), |
|||
), |
|||
) |
|||
}); |
|||
|
|||
init::LateResources { |
|||
usb_dev, |
|||
usb_class, |
|||
timer, |
|||
debouncer: Debouncer::new(PressedKeys::default(), PressedKeys::default(), 5), |
|||
matrix: matrix.unwrap(), |
|||
layout: Layout::new(LAYERS), |
|||
} |
|||
} |
|||
|
|||
#[task(binds = USB, priority = 2, resources = [usb_dev, usb_class])] |
|||
fn usb_rx(mut c: usb_rx::Context) { |
|||
usb_poll(&mut c.resources.usb_dev, &mut c.resources.usb_class); |
|||
} |
|||
|
|||
#[task(binds = TIM3, priority = 1, resources = [usb_class, matrix, debouncer, layout, timer])] |
|||
fn tick(mut c: tick::Context) { |
|||
c.resources.timer.wait().ok(); |
|||
|
|||
for event in c |
|||
.resources |
|||
.debouncer |
|||
.events(c.resources.matrix.get().unwrap()) |
|||
{ |
|||
send_report(c.resources.layout.event(event), &mut c.resources.usb_class); |
|||
} |
|||
send_report(c.resources.layout.tick(), &mut c.resources.usb_class); |
|||
} |
|||
}; |
|||
|
|||
fn send_report(iter: impl Iterator<Item = KeyCode>, usb_class: &mut resources::usb_class<'_>) { |
|||
use rtfm::Mutex; |
|||
let report: KbHidReport = iter.collect(); |
|||
if usb_class.lock(|k| k.device_mut().set_keyboard_report(report.clone())) { |
|||
while let Ok(0) = usb_class.lock(|k| k.write(report.as_bytes())) {} |
|||
} |
|||
} |
|||
|
|||
fn usb_poll(usb_dev: &mut UsbDevice, keyboard: &mut UsbClass) { |
|||
if usb_dev.poll(&mut [keyboard]) { |
|||
keyboard.poll(); |
|||
} |
|||
} |
Loading…
Reference in new issue