Commands for reading and setting keyboard map
This commit is contained in:
parent
432c4f64d2
commit
de26cdfa74
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#ifndef __SCRATCH__
|
#ifndef __SCRATCH__
|
||||||
#include <board/scratch.h>
|
#include <board/scratch.h>
|
||||||
|
#include <board/keymap.h>
|
||||||
#endif
|
#endif
|
||||||
#include <board/smfi.h>
|
#include <board/smfi.h>
|
||||||
#include <common/command.h>
|
#include <common/command.h>
|
||||||
@ -178,6 +179,39 @@ static enum Result cmd_fan_set(void) {
|
|||||||
// Failed if fan not found
|
// Failed if fan not found
|
||||||
return RES_ERR;
|
return RES_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum Result cmd_keymap_get(void) {
|
||||||
|
int layer = smfi_cmd[2];
|
||||||
|
int output = smfi_cmd[3];
|
||||||
|
int input = smfi_cmd[4];
|
||||||
|
|
||||||
|
if (layer < KM_LAY && output < KM_OUT && input < KM_IN) {
|
||||||
|
uint16_t key = KEYMAP[layer][output][input];
|
||||||
|
smfi_cmd[5] = (uint8_t)key;
|
||||||
|
smfi_cmd[6] = (uint8_t)(key >> 8);
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed if keyboard mapping not found
|
||||||
|
return RES_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum Result cmd_keymap_set(void) {
|
||||||
|
int layer = smfi_cmd[2];
|
||||||
|
int output = smfi_cmd[3];
|
||||||
|
int input = smfi_cmd[4];
|
||||||
|
|
||||||
|
if (layer < KM_LAY && output < KM_OUT && input < KM_IN) {
|
||||||
|
uint16_t key =
|
||||||
|
((uint16_t)smfi_cmd[5]) |
|
||||||
|
(((uint16_t)smfi_cmd[6]) << 8);
|
||||||
|
KEYMAP[layer][output][input] = key;
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed if keyboard mapping not found
|
||||||
|
return RES_ERR;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set a watchdog timer of 10 seconds
|
// Set a watchdog timer of 10 seconds
|
||||||
@ -230,6 +264,12 @@ void smfi_event(void) {
|
|||||||
case CMD_FAN_SET:
|
case CMD_FAN_SET:
|
||||||
smfi_cmd[1] = cmd_fan_set();
|
smfi_cmd[1] = cmd_fan_set();
|
||||||
break;
|
break;
|
||||||
|
case CMD_KEYMAP_GET:
|
||||||
|
smfi_cmd[1] = cmd_keymap_get();
|
||||||
|
break;
|
||||||
|
case CMD_KEYMAP_SET:
|
||||||
|
smfi_cmd[1] = cmd_keymap_set();
|
||||||
|
break;
|
||||||
#endif // __SCRATCH__
|
#endif // __SCRATCH__
|
||||||
default:
|
default:
|
||||||
// Command not found
|
// Command not found
|
||||||
|
@ -22,6 +22,10 @@ enum Command {
|
|||||||
CMD_FAN_GET = 7,
|
CMD_FAN_GET = 7,
|
||||||
// Set fan speeds
|
// Set fan speeds
|
||||||
CMD_FAN_SET = 8,
|
CMD_FAN_SET = 8,
|
||||||
|
// Get keyboard map index
|
||||||
|
CMD_KEYMAP_GET = 9,
|
||||||
|
// Set keyboard map index
|
||||||
|
CMD_KEYMAP_SET = 10,
|
||||||
//TODO
|
//TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ pub enum Cmd {
|
|||||||
Reset = 6,
|
Reset = 6,
|
||||||
FanGet = 7,
|
FanGet = 7,
|
||||||
FanSet = 8,
|
FanSet = 8,
|
||||||
|
KeymapGet = 9,
|
||||||
|
KeymapSet = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CMD_SPI_FLAG_READ: u8 = 1 << 0;
|
pub const CMD_SPI_FLAG_READ: u8 = 1 << 0;
|
||||||
@ -195,6 +197,26 @@ impl<T: Timeout> Ec<T> {
|
|||||||
self.write(3, duty);
|
self.write(3, duty);
|
||||||
self.command(Cmd::FanSet)
|
self.command(Cmd::FanSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn keymap_get(&mut self, layer: u8, output: u8, input: u8) -> Result<u16, Error> {
|
||||||
|
self.write(2, layer);
|
||||||
|
self.write(3, output);
|
||||||
|
self.write(4, input);
|
||||||
|
self.command(Cmd::KeymapGet)?;
|
||||||
|
Ok(
|
||||||
|
(self.read(5) as u16) |
|
||||||
|
((self.read(6) as u16) << 8)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn keymap_set(&mut self, layer: u8, output: u8, input: u8, value: u16) -> Result<(), Error> {
|
||||||
|
self.write(2, layer);
|
||||||
|
self.write(3, output);
|
||||||
|
self.write(4, input);
|
||||||
|
self.write(5, value as u8);
|
||||||
|
self.write(6, (value >> 8) as u8);
|
||||||
|
self.command(Cmd::KeymapSet)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EcSpi<'a, T: Timeout> {
|
pub struct EcSpi<'a, T: Timeout> {
|
||||||
|
103
tool/src/main.rs
103
tool/src/main.rs
@ -12,7 +12,7 @@ use std::{
|
|||||||
fs,
|
fs,
|
||||||
io,
|
io,
|
||||||
process,
|
process,
|
||||||
str,
|
str::{self, FromStr},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
@ -296,18 +296,64 @@ unsafe fn fan_set(index: u8, duty: u8) -> Result<(), Error> {
|
|||||||
ec.fan_set(index, duty)
|
ec.fan_set(index, duty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn keymap_get(layer: u8, output: u8, input: u8) -> Result<(), Error> {
|
||||||
|
iopl();
|
||||||
|
|
||||||
|
let mut ec = Ec::new(
|
||||||
|
StdTimeout::new(Duration::new(1, 0)),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let value = ec.keymap_get(layer, output, input)?;
|
||||||
|
println!("{:04X}", value);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn keymap_set(layer: u8, output: u8, input: u8, value: u16) -> Result<(), Error> {
|
||||||
|
iopl();
|
||||||
|
|
||||||
|
let mut ec = Ec::new(
|
||||||
|
StdTimeout::new(Duration::new(1, 0)),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
ec.keymap_set(layer, output, input, value)
|
||||||
|
}
|
||||||
|
|
||||||
fn usage() {
|
fn usage() {
|
||||||
eprintln!(" console");
|
eprintln!(" console");
|
||||||
eprintln!(" flash [file]");
|
eprintln!(" flash [file]");
|
||||||
eprintln!(" flash_backup [file]");
|
eprintln!(" flash_backup [file]");
|
||||||
eprintln!(" fan [index] <duty>");
|
eprintln!(" fan [index] <duty>");
|
||||||
eprintln!(" info");
|
eprintln!(" info");
|
||||||
|
eprintln!(" keymap [layer] [output] [input] <value>");
|
||||||
eprintln!(" print [message]");
|
eprintln!(" print [message]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_arg_opt<I: Iterator<Item=String>, F: FromStr>(args: &mut I, name: &str) -> Option<F> {
|
||||||
|
match args.next() {
|
||||||
|
Some(arg) => match arg.parse::<F>() {
|
||||||
|
Ok(ok) => Some(ok),
|
||||||
|
Err(_err) => {
|
||||||
|
eprintln!("failed to parse {}: '{}'", name, arg);
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_arg<I: Iterator<Item=String>, F: FromStr>(args: &mut I, name: &str) -> F {
|
||||||
|
match parse_arg_opt(args, name) {
|
||||||
|
Some(some) => some,
|
||||||
|
None => {
|
||||||
|
eprintln!("no {} provided", name);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
|
|
||||||
match args.next() {
|
match args.next() {
|
||||||
Some(arg) => match arg.as_str() {
|
Some(arg) => match arg.as_str() {
|
||||||
"console" => match unsafe { console() } {
|
"console" => match unsafe { console() } {
|
||||||
@ -317,22 +363,17 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fan" => match args.next() {
|
"fan" => {
|
||||||
Some(index_str) => match index_str.parse::<u8>() {
|
let index = parse_arg(&mut args, "index");
|
||||||
Ok(index) => match args.next() {
|
let duty_opt = parse_arg_opt(&mut args, "duty");
|
||||||
Some(duty_str) => match duty_str.parse::<u8>() {
|
match duty_opt {
|
||||||
Ok(duty) => match unsafe { fan_set(index, duty) } {
|
Some(duty) => match unsafe { fan_set(index, duty) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
|
eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Err(err) => {
|
|
||||||
eprintln!("failed to parse '{}': {:X?}", duty_str, err);
|
|
||||||
process::exit(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None => match unsafe { fan_get(index) } {
|
None => match unsafe { fan_get(index) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -340,16 +381,7 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
Err(err) => {
|
|
||||||
eprintln!("failed to parse '{}': {:X?}", index_str, err);
|
|
||||||
process::exit(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
eprintln!("no index provided");
|
|
||||||
process::exit(1);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"flash" => match args.next() {
|
"flash" => match args.next() {
|
||||||
Some(path) => match unsafe { flash(&path, SpiTarget::Main) } {
|
Some(path) => match unsafe { flash(&path, SpiTarget::Main) } {
|
||||||
@ -384,6 +416,33 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"keymap" => {
|
||||||
|
let layer = parse_arg(&mut args, "layer");
|
||||||
|
let output = parse_arg(&mut args, "output");
|
||||||
|
let input = parse_arg(&mut args, "input");
|
||||||
|
match args.next() {
|
||||||
|
Some(value_str) => match u16::from_str_radix(&value_str, 16) {
|
||||||
|
Ok(value) => match unsafe { keymap_set(layer, output, input, value) } {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to set keymap {}, {}, {} to {}: {:X?}", layer, output, input, value, err);
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to parse value: '{}': {}", arg, err);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => match unsafe { keymap_get(layer, output, input) } {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to get keymap {}, {}, {}: {:X?}", layer, output, input, err);
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
"print" => for mut arg in args {
|
"print" => for mut arg in args {
|
||||||
arg.push('\n');
|
arg.push('\n');
|
||||||
match unsafe { print(&arg.as_bytes()) } {
|
match unsafe { print(&arg.as_bytes()) } {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user