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"
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
reqwest = { version = "0.11.23", features = ["blocking"] }
|
||||
|
||||
|
||||
[profile.release]
|
||||
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")]
|
||||
pub struct BacklightBreathing {
|
||||
pub enabled: bool,
|
||||
pub period: std::time::Duration,
|
||||
pub period: core::time::Duration,
|
||||
}
|
||||
|
||||
pub struct Backlight<'d> {
|
||||
pub pins: Vec<Output<'d, AnyPin>>,
|
||||
pub struct Backlight<'d, const PIN_COUNT: usize> {
|
||||
pub pins: [Output<'d, AnyPin>; PIN_COUNT],
|
||||
pub on: bool,
|
||||
pub default_on: bool,
|
||||
pub lvl: BacklightLevel,
|
||||
@ -18,8 +18,8 @@ pub struct Backlight<'d> {
|
||||
pub breathing: BacklightBreathing,
|
||||
}
|
||||
|
||||
impl<'d> Backlight<'d> {
|
||||
pub fn new(pins: Vec<Output<'d, AnyPin>>, default_lvl: BacklightLevel) -> Self {
|
||||
impl<'d, const PIN_COUNT: usize> Backlight<'d, PIN_COUNT> {
|
||||
pub fn new(pins: [Output<'d, AnyPin>; PIN_COUNT], default_lvl: BacklightLevel) -> Self {
|
||||
let mut bl = Self {
|
||||
pins,
|
||||
on: cfg!(feature = "backlight_default_on"),
|
||||
@ -29,36 +29,29 @@ impl<'d> Backlight<'d> {
|
||||
#[cfg(feature = "backlight_breathing")]
|
||||
breathing: BacklightBreathing {
|
||||
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
|
||||
}
|
||||
|
||||
fn backlight_pin_on<'d>(pin: &mut Output<'d, AnyPin>) {
|
||||
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) {
|
||||
pub fn backlight_pins_on(&mut self) {
|
||||
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 {
|
||||
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
|
||||
QkBasic = 0x0000,
|
||||
QkBasicMax = 0x00FF,
|
||||
@ -60,6 +61,7 @@ pub enum QkKeycodeRanges {
|
||||
// QkUnicodemapPairMax = 0xFFFF,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum QkKeycodeDefines {
|
||||
// Keycodes
|
||||
KcNo = 0x0000,
|
||||
@ -762,7 +764,7 @@ enum QkKeycodeDefines {
|
||||
|
||||
// Alias
|
||||
XXXXXXX = QkKeycodeDefines::KcNo as isize,
|
||||
KcTrns = Keycodes::KcTransparent,
|
||||
KcTrns = QkKeycodeDefines::KcTransparent as isize,
|
||||
KcEnt = Keycodes::KcEnter,
|
||||
KcEsc = Keycodes::KcEscape,
|
||||
KcBspc = Keycodes::KcBackspace,
|
||||
@ -1338,3 +1340,4 @@ enum QkKeycodeDefines {
|
||||
QkRep = Keycodes::QkRepeatKey,
|
||||
QkArep = Keycodes::QkAltRepeatKey,
|
||||
}
|
||||
*/
|
@ -1,2 +1,5 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
pub mod backlight;
|
||||
pub mod keycodes;
|
||||
|
@ -11,5 +11,5 @@ use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p = init(Default::default());
|
||||
let _p = init(Default::default());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user