Add agents
This commit is contained in:
parent
d070ff2f91
commit
4561bf5606
8
.cargo/config.toml
Normal file
8
.cargo/config.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||||
|
runner = "probe-rs run --chip RP2040"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||||
|
|
||||||
|
[env]
|
||||||
|
DEFMT_LOG = "debug"
|
754
Cargo.lock
generated
754
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -55,5 +55,9 @@ pio-proc = "0.2"
|
|||||||
pio = "0.2.1"
|
pio = "0.2.1"
|
||||||
rand = { version = "0.8.5", default-features = false }
|
rand = { version = "0.8.5", default-features = false }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
reqwest = { version = "0.11.23", features = ["blocking"] }
|
||||||
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
242
build.rs
Normal file
242
build.rs
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::env;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Put `memory.x` in our output directory and ensure it's
|
||||||
|
// on the linker search path.
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// By default, Cargo will re-run a build script whenever
|
||||||
|
// any file in the project changes. By specifying `memory.x`
|
||||||
|
// here, we ensure the build script is only re-run when
|
||||||
|
// `memory.x` is changed.
|
||||||
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-arg-bins=--nmagic");
|
||||||
|
println!("cargo:rustc-link-arg-bins=-Tlink.x");
|
||||||
|
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
|
||||||
|
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||||
|
|
||||||
|
let client = reqwest::blocking::Client::new();
|
||||||
|
let res = if Path::new("./target/keycodes.h").exists() {
|
||||||
|
std::fs::read_to_string("./target/keycodes.h").unwrap()
|
||||||
|
} else {
|
||||||
|
let res = client
|
||||||
|
.get("https://raw.githubusercontent.com/qmk/qmk_firmware/master/quantum/keycodes.h")
|
||||||
|
.send()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.unwrap();
|
||||||
|
std::fs::write("./target/keycodes.h", res.as_bytes()).unwrap();
|
||||||
|
res
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut log_file = std::fs::OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.append(false)
|
||||||
|
.write(true)
|
||||||
|
.open("./target/tokens.log")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut global_register = HashMap::with_capacity(9086);
|
||||||
|
let mut enums = Vec::with_capacity(64);
|
||||||
|
let iter = res.lines();
|
||||||
|
let mut is_block_comment = false;
|
||||||
|
for line in iter {
|
||||||
|
parse_line(
|
||||||
|
line,
|
||||||
|
&mut enums,
|
||||||
|
&mut is_block_comment,
|
||||||
|
&mut global_register,
|
||||||
|
&mut log_file,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut mod_file = std::fs::OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.append(false)
|
||||||
|
.write(true)
|
||||||
|
.open("./src/keycodes/mod.rs")
|
||||||
|
.unwrap();
|
||||||
|
for info in enums {
|
||||||
|
mod_file.write_fmt(format_args!("{info}\n")).unwrap();
|
||||||
|
mod_file.flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_line(
|
||||||
|
line: &str,
|
||||||
|
enums: &mut Vec<EnumInfo>,
|
||||||
|
is_block_comment: &mut bool,
|
||||||
|
global_register: &mut HashMap<String, String>,
|
||||||
|
log_file: &mut File,
|
||||||
|
) {
|
||||||
|
log_file.write_fmt(format_args!("Line {line:?}\n")).unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
|
||||||
|
let line = line.trim();
|
||||||
|
let mut it = line
|
||||||
|
.split_ascii_whitespace()
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.peekable();
|
||||||
|
while let Some(token) = it.next().map(ToOwned::to_owned) {
|
||||||
|
log_file
|
||||||
|
.write_fmt(format_args!("token {token:?}\n"))
|
||||||
|
.unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
println!("token {token:?}");
|
||||||
|
match token.as_str() {
|
||||||
|
_ if token.starts_with("#") => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
"//" => {
|
||||||
|
log_file
|
||||||
|
.write_fmt(format_args!("skip {token:?}\n"))
|
||||||
|
.unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
"enum" => {
|
||||||
|
log_file
|
||||||
|
.write_fmt(format_args!("new enum {token:?}\n"))
|
||||||
|
.unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
enums.push(EnumInfo::new(
|
||||||
|
it.next().expect("enum must have name").to_owned(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
"{" => {}
|
||||||
|
"," => {}
|
||||||
|
"}" | "};" => {}
|
||||||
|
_ if token.starts_with("/*") && token.ends_with("*/") => {
|
||||||
|
println!("closed comment");
|
||||||
|
}
|
||||||
|
_ if token.ends_with("*/") => {
|
||||||
|
*is_block_comment = false;
|
||||||
|
}
|
||||||
|
_ if *is_block_comment || token.starts_with("/*") => {
|
||||||
|
*is_block_comment = true;
|
||||||
|
println!("comment {token:?}");
|
||||||
|
log_file
|
||||||
|
.write_fmt(format_args!("comment {token:?}\n"))
|
||||||
|
.unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
|
||||||
|
while let Some(t) = it.next() {
|
||||||
|
println!("looking for \"*/\" : {t:?}");
|
||||||
|
log_file
|
||||||
|
.write_fmt(format_args!("looking for \"*/\" : {t:?}\n"))
|
||||||
|
.unwrap();
|
||||||
|
log_file.flush().unwrap();
|
||||||
|
if t.ends_with("*/") {
|
||||||
|
println!("ends looking for closing comment with {t:?}");
|
||||||
|
*is_block_comment = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if enums.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let name = token.as_str();
|
||||||
|
println!("new variant name is {name:?}");
|
||||||
|
it.next().expect("variant must be followed by =");
|
||||||
|
let val = it.next().expect("variant must have value").trim_end_matches(",");
|
||||||
|
enums
|
||||||
|
.last_mut()
|
||||||
|
.expect("must have enum token before here")
|
||||||
|
.add_variant(name, val, global_register);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type VariantName = String;
|
||||||
|
pub type VariantValue = String;
|
||||||
|
pub type EnumName = String;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct EnumInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub variants: HashMap<VariantName, VariantValue>,
|
||||||
|
pub values_cache: HashSet<VariantValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for EnumInfo {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("#[derive(Debug)]\n")?;
|
||||||
|
f.write_str("#[repr(C)]\n")?;
|
||||||
|
f.write_str("pub enum ")?;
|
||||||
|
f.write_str(Self::rust_enum_name(&self.name).as_str())?;
|
||||||
|
f.write_str(" {\n")?;
|
||||||
|
for (var_name, var_val) in &self.variants {
|
||||||
|
f.write_fmt(format_args!(
|
||||||
|
" {} = {},\n",
|
||||||
|
Self::rust_enum_name(var_name),
|
||||||
|
var_val
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
f.write_str("}")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnumInfo {
|
||||||
|
const CACHE_SIZE: usize = 1024 * 5;
|
||||||
|
pub fn new(name: String) -> EnumInfo {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
variants: HashMap::with_capacity(Self::CACHE_SIZE),
|
||||||
|
values_cache: HashSet::with_capacity(Self::CACHE_SIZE),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_variant<'global>(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
val: &str,
|
||||||
|
global_register: &'global mut HashMap<VariantName, EnumName>,
|
||||||
|
) {
|
||||||
|
println!("adding variant {name:?} {val:?}");
|
||||||
|
if self.values_cache.contains(val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.variants.insert(
|
||||||
|
name.to_owned(),
|
||||||
|
global_register
|
||||||
|
.get(val)
|
||||||
|
.map(|enum_name| format!("{enum_name}::{val} as usize"))
|
||||||
|
.unwrap_or_else(|| val.to_owned()),
|
||||||
|
);
|
||||||
|
global_register.insert(name.to_owned(), self.name.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rust_enum_name(name: &str) -> String {
|
||||||
|
let mut prev_underscore = false;
|
||||||
|
name.chars()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(idx, c)| {
|
||||||
|
if idx == 0 {
|
||||||
|
Some(c.to_ascii_uppercase())
|
||||||
|
} else if c == '_' {
|
||||||
|
prev_underscore = true;
|
||||||
|
None
|
||||||
|
} else if prev_underscore {
|
||||||
|
prev_underscore = false;
|
||||||
|
Some(c.to_ascii_uppercase())
|
||||||
|
} else {
|
||||||
|
Some(c)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
17
memory.x
Normal file
17
memory.x
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
MEMORY {
|
||||||
|
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||||
|
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
|
||||||
|
|
||||||
|
/* Pick one of the two options for RAM layout */
|
||||||
|
|
||||||
|
/* OPTION A: Use all RAM banks as one big block */
|
||||||
|
/* Reasonable, unless you are doing something */
|
||||||
|
/* really particular with DMA or other concurrent */
|
||||||
|
/* access that would benefit from striping */
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 264K
|
||||||
|
|
||||||
|
/* OPTION B: Keep the unstriped sections separate */
|
||||||
|
/* RAM: ORIGIN = 0x20000000, LENGTH = 256K */
|
||||||
|
/* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */
|
||||||
|
/* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */
|
||||||
|
}
|
12
rust-toolchain.toml
Normal file
12
rust-toolchain.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "stable"
|
||||||
|
components = [ "rust-src", "rustfmt", "llvm-tools" ]
|
||||||
|
targets = [
|
||||||
|
"thumbv7em-none-eabi",
|
||||||
|
"thumbv7m-none-eabi",
|
||||||
|
"thumbv6m-none-eabi",
|
||||||
|
"thumbv7em-none-eabihf",
|
||||||
|
"thumbv8m.main-none-eabihf",
|
||||||
|
"riscv32imac-unknown-none-elf",
|
||||||
|
"wasm32-unknown-unknown",
|
||||||
|
]
|
@ -5,11 +5,11 @@ pub type BacklightLevel = u8;
|
|||||||
#[cfg(feature = "backlight_breathing")]
|
#[cfg(feature = "backlight_breathing")]
|
||||||
pub struct BacklightBreathing {
|
pub struct BacklightBreathing {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub period: std::time::Duration,
|
pub period: core::time::Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Backlight<'d> {
|
pub struct Backlight<'d, const PIN_COUNT: usize> {
|
||||||
pub pins: Vec<Output<'d, AnyPin>>,
|
pub pins: [Output<'d, AnyPin>; PIN_COUNT],
|
||||||
pub on: bool,
|
pub on: bool,
|
||||||
pub default_on: bool,
|
pub default_on: bool,
|
||||||
pub lvl: BacklightLevel,
|
pub lvl: BacklightLevel,
|
||||||
@ -18,8 +18,8 @@ pub struct Backlight<'d> {
|
|||||||
pub breathing: BacklightBreathing,
|
pub breathing: BacklightBreathing,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Backlight<'d> {
|
impl<'d, const PIN_COUNT: usize> Backlight<'d, PIN_COUNT> {
|
||||||
pub fn new(pins: Vec<Output<'d, AnyPin>>, default_lvl: BacklightLevel) -> Self {
|
pub fn new(pins: [Output<'d, AnyPin>; PIN_COUNT], default_lvl: BacklightLevel) -> Self {
|
||||||
let mut bl = Self {
|
let mut bl = Self {
|
||||||
pins,
|
pins,
|
||||||
on: cfg!(feature = "backlight_default_on"),
|
on: cfg!(feature = "backlight_default_on"),
|
||||||
@ -29,36 +29,29 @@ impl<'d> Backlight<'d> {
|
|||||||
#[cfg(feature = "backlight_breathing")]
|
#[cfg(feature = "backlight_breathing")]
|
||||||
breathing: BacklightBreathing {
|
breathing: BacklightBreathing {
|
||||||
enabled: cfg!(feature = "backlight_breathing_default_on"),
|
enabled: cfg!(feature = "backlight_breathing_default_on"),
|
||||||
period: std::time::Duration::from_millis(66),
|
period: core::time::Duration::from_millis(66),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
bl.backlight_pins_off();
|
bl.backlight_pins_off();
|
||||||
bl
|
bl
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backlight_pin_on<'d>(pin: &mut Output<'d, AnyPin>) {
|
pub fn backlight_pins_on(&mut self) {
|
||||||
if cfg!(feature = "backlight_on_state") {
|
|
||||||
pin.set_high();
|
|
||||||
} else {
|
|
||||||
pin.set_low();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn backlight_pin_off<'d>(pin: &mut Output<'d, AnyPin>) {
|
|
||||||
if cfg!(feature = "backlight_on_state") {
|
|
||||||
pin.set_low();
|
|
||||||
} else {
|
|
||||||
pin.set_high();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn backlight_pins_on<'d>(&mut self) {
|
|
||||||
for pin in &mut self.pins {
|
for pin in &mut self.pins {
|
||||||
Self::backlight_pin_on(pin);
|
if cfg!(feature = "backlight_on_state") {
|
||||||
|
pin.set_high();
|
||||||
|
} else {
|
||||||
|
pin.set_low();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn backlight_pins_off<'d>(&mut self) {
|
pub fn backlight_pins_off(&mut self) {
|
||||||
for pin in &mut self.pins {
|
for pin in &mut self.pins {
|
||||||
Self::backlight_pin_off(pin);
|
if cfg!(feature = "backlight_on_state") {
|
||||||
|
pin.set_low();
|
||||||
|
} else {
|
||||||
|
pin.set_high();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1340
src/keycodes/mod.rs
Normal file
1340
src/keycodes/mod.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
|||||||
pub enum QkKeycodeRanges {
|
/*#[repr(C)]
|
||||||
|
pub enum QkKeycodeRange {
|
||||||
// Ranges
|
// Ranges
|
||||||
QkBasic = 0x0000,
|
QkBasic = 0x0000,
|
||||||
QkBasicMax = 0x00FF,
|
QkBasicMax = 0x00FF,
|
||||||
@ -60,6 +61,7 @@ pub enum QkKeycodeRanges {
|
|||||||
// QkUnicodemapPairMax = 0xFFFF,
|
// QkUnicodemapPairMax = 0xFFFF,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
enum QkKeycodeDefines {
|
enum QkKeycodeDefines {
|
||||||
// Keycodes
|
// Keycodes
|
||||||
KcNo = 0x0000,
|
KcNo = 0x0000,
|
||||||
@ -762,7 +764,7 @@ enum QkKeycodeDefines {
|
|||||||
|
|
||||||
// Alias
|
// Alias
|
||||||
XXXXXXX = QkKeycodeDefines::KcNo as isize,
|
XXXXXXX = QkKeycodeDefines::KcNo as isize,
|
||||||
KcTrns = Keycodes::KcTransparent,
|
KcTrns = QkKeycodeDefines::KcTransparent as isize,
|
||||||
KcEnt = Keycodes::KcEnter,
|
KcEnt = Keycodes::KcEnter,
|
||||||
KcEsc = Keycodes::KcEscape,
|
KcEsc = Keycodes::KcEscape,
|
||||||
KcBspc = Keycodes::KcBackspace,
|
KcBspc = Keycodes::KcBackspace,
|
||||||
@ -1338,3 +1340,4 @@ enum QkKeycodeDefines {
|
|||||||
QkRep = Keycodes::QkRepeatKey,
|
QkRep = Keycodes::QkRepeatKey,
|
||||||
QkArep = Keycodes::QkAltRepeatKey,
|
QkArep = Keycodes::QkAltRepeatKey,
|
||||||
}
|
}
|
||||||
|
*/
|
@ -1,2 +1,5 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
pub mod backlight;
|
pub mod backlight;
|
||||||
pub mod keycodes;
|
pub mod keycodes;
|
||||||
|
@ -11,5 +11,5 @@ use {defmt_rtt as _, panic_probe as _};
|
|||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = init(Default::default());
|
let _p = init(Default::default());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user