Support RMK device config
This commit is contained in:
parent
8e304540ea
commit
5004e8dfdf
|
|
@ -3,8 +3,6 @@ name = "acid-firmware"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ['Jakub "Limeth" Hlusička']
|
authors = ['Jakub "Limeth" Hlusička']
|
||||||
description = "Firmware for the ACID keyboard"
|
description = "Firmware for the ACID keyboard"
|
||||||
homepage = "https://github.com/haobogu/rmk"
|
|
||||||
repository = "https://github.com/haobogu/rmk"
|
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
||||||
|
|
@ -149,16 +149,58 @@ fn generate_vial_config() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let vial_cfg = json::parse(&content).unwrap();
|
let vial_cfg = json::parse(&content).unwrap();
|
||||||
let vial_cfg_string = json::stringify(vial_cfg.clone());
|
|
||||||
let mut keyboard_def_compressed: Vec<u8> = Vec::new();
|
|
||||||
XzEncoder::new(vial_cfg_string.as_bytes(), 6)
|
|
||||||
.read_to_end(&mut keyboard_def_compressed)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let keyboard_id: Vec<u8> = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA];
|
let keyboard_def_compressed: Vec<u8> = {
|
||||||
|
let vial_cfg_string = json::stringify(vial_cfg.clone());
|
||||||
|
let mut keyboard_def_compressed = Vec::new();
|
||||||
|
XzEncoder::new(vial_cfg_string.as_bytes(), 6)
|
||||||
|
.read_to_end(&mut keyboard_def_compressed)
|
||||||
|
.unwrap();
|
||||||
|
keyboard_def_compressed
|
||||||
|
};
|
||||||
|
// This is a firmware-unique randomly generated ID.
|
||||||
|
// If you fork this repo to make your own firmware, you should change this.
|
||||||
|
let keyboard_id: Vec<u8> = vec![0x9a, 0x8a, 0x08, 0xae, 0x87, 0xcd, 0xc7, 0xb9];
|
||||||
|
let keyboard_name: &str = {
|
||||||
|
let JsonValue::Object(vial_cfg) = &vial_cfg else {
|
||||||
|
panic!("The root element in `vial.json` is not an object.");
|
||||||
|
};
|
||||||
|
vial_cfg
|
||||||
|
.get("name")
|
||||||
|
.expect("No `name` in `vial.json`.")
|
||||||
|
.as_str()
|
||||||
|
.expect("`name` in `vial.json` is not a string.")
|
||||||
|
};
|
||||||
|
let vendor_id: u16 = {
|
||||||
|
let JsonValue::Object(vial_cfg) = &vial_cfg else {
|
||||||
|
panic!("The root element in `vial.json` is not an object.");
|
||||||
|
};
|
||||||
|
let vendor_id_string = vial_cfg
|
||||||
|
.get("vendorId")
|
||||||
|
.expect("No `vendorId` in `vial.json`.")
|
||||||
|
.as_str()
|
||||||
|
.expect("`vendorId` in `vial.json` is not a string.");
|
||||||
|
assert!(vendor_id_string.starts_with("0x"));
|
||||||
|
u16::from_str_radix(&vendor_id_string[2..], 16).expect("Invalid vendor ID.")
|
||||||
|
};
|
||||||
|
let product_id: u16 = {
|
||||||
|
let JsonValue::Object(vial_cfg) = &vial_cfg else {
|
||||||
|
panic!("The root element in `vial.json` is not an object.");
|
||||||
|
};
|
||||||
|
let product_id_string = vial_cfg
|
||||||
|
.get("productId")
|
||||||
|
.expect("No `productId` in `vial.json`.")
|
||||||
|
.as_str()
|
||||||
|
.expect("`productId` in `vial.json` is not a string.");
|
||||||
|
assert!(product_id_string.starts_with("0x"));
|
||||||
|
u16::from_str_radix(&product_id_string[2..], 16).expect("Invalid product ID.")
|
||||||
|
};
|
||||||
let const_declarations = [
|
let const_declarations = [
|
||||||
const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed),
|
const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed),
|
||||||
const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id),
|
const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id),
|
||||||
|
const_declaration!(pub VIAL_KEYBOARD_NAME = keyboard_name),
|
||||||
|
const_declaration!(pub VIAL_VENDOR_ID = vendor_id),
|
||||||
|
const_declaration!(pub VIAL_PRODUCT_ID = product_id),
|
||||||
]
|
]
|
||||||
.map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str())
|
.map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str())
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::collections::vec_deque::VecDeque;
|
use alloc::collections::vec_deque::VecDeque;
|
||||||
|
use alloc::format;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
|
|
@ -40,6 +41,7 @@ use esp_bootloader_esp_idf::partitions::PartitionTable;
|
||||||
use esp_hal::Blocking;
|
use esp_hal::Blocking;
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig};
|
use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig};
|
||||||
|
use esp_hal::efuse::Efuse;
|
||||||
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
||||||
use esp_hal::i2c::master::{I2c, I2cAddress};
|
use esp_hal::i2c::master::{I2c, I2cAddress};
|
||||||
use esp_hal::interrupt::software::SoftwareInterruptControl;
|
use esp_hal::interrupt::software::SoftwareInterruptControl;
|
||||||
|
|
@ -55,9 +57,12 @@ use esp_hal::timer::timg::TimerGroup;
|
||||||
use esp_rtos::embassy::Executor;
|
use esp_rtos::embassy::Executor;
|
||||||
use esp_storage::FlashStorage;
|
use esp_storage::FlashStorage;
|
||||||
use indoc::writedoc;
|
use indoc::writedoc;
|
||||||
|
use itertools::Itertools;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rmk::channel::{CONTROLLER_CHANNEL, ControllerSub};
|
use rmk::channel::{CONTROLLER_CHANNEL, ControllerSub};
|
||||||
use rmk::config::{BehaviorConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig};
|
use rmk::config::{
|
||||||
|
BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig,
|
||||||
|
};
|
||||||
use rmk::controller::{Controller, EventController};
|
use rmk::controller::{Controller, EventController};
|
||||||
use rmk::debounce::default_debouncer::DefaultDebouncer;
|
use rmk::debounce::default_debouncer::DefaultDebouncer;
|
||||||
use rmk::event::ControllerEvent;
|
use rmk::event::ControllerEvent;
|
||||||
|
|
@ -77,7 +82,10 @@ use crate::logging::LOG_LEVEL_FILTER;
|
||||||
use crate::matrix::IoeMatrix;
|
use crate::matrix::IoeMatrix;
|
||||||
use crate::peripherals::st7701s::St7701s;
|
use crate::peripherals::st7701s::St7701s;
|
||||||
use crate::ui::backend::{FramebufferPtr, SlintBackend};
|
use crate::ui::backend::{FramebufferPtr, SlintBackend};
|
||||||
use crate::vial::{CustomKeycodes, VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
|
use crate::vial::{
|
||||||
|
CustomKeycodes, VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID, VIAL_KEYBOARD_NAME, VIAL_PRODUCT_ID,
|
||||||
|
VIAL_VENDOR_ID,
|
||||||
|
};
|
||||||
|
|
||||||
mutually_exclusive_features::none_or_one_of!["usb-log", "alt-log", "rtt-log"];
|
mutually_exclusive_features::none_or_one_of!["usb-log", "alt-log", "rtt-log"];
|
||||||
|
|
||||||
|
|
@ -388,7 +396,28 @@ async fn main(_spawner: Spawner) {
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
// Retrieve the hardware-unique MAC address.
|
||||||
|
let mac_address = Efuse::read_base_mac_address();
|
||||||
|
static SERIAL_NUMBER: StaticCell<Box<str>> = StaticCell::new();
|
||||||
|
let serial_number = SERIAL_NUMBER.init_with(|| {
|
||||||
|
/// A magic prefix string that is required for the device to be recognized by the Vial GUI.
|
||||||
|
const VIAL_SERIAL_PREFIX: &str = "vial:f64c2b3c";
|
||||||
|
format!(
|
||||||
|
"{VIAL_SERIAL_PREFIX}:acid:{:02x}",
|
||||||
|
mac_address.iter().format("")
|
||||||
|
)
|
||||||
|
.into_boxed_str()
|
||||||
|
});
|
||||||
|
let device_config = DeviceConfig {
|
||||||
|
vid: VIAL_VENDOR_ID,
|
||||||
|
pid: VIAL_PRODUCT_ID,
|
||||||
|
manufacturer: "",
|
||||||
|
product_name: VIAL_KEYBOARD_NAME,
|
||||||
|
serial_number,
|
||||||
|
};
|
||||||
|
info!("RMK Device Config: {device_config:#04x?}");
|
||||||
let rmk_config = RmkConfig {
|
let rmk_config = RmkConfig {
|
||||||
|
device_config,
|
||||||
vial_config,
|
vial_config,
|
||||||
storage_config,
|
storage_config,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue