Commands for reading and setting keyboard map
This commit is contained in:
		
				
					committed by
					
						
						Jeremy Soller
					
				
			
			
				
	
			
			
			
						parent
						
							432c4f64d2
						
					
				
				
					commit
					de26cdfa74
				
			@@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __SCRATCH__
 | 
			
		||||
    #include <board/scratch.h>
 | 
			
		||||
    #include <board/keymap.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <board/smfi.h>
 | 
			
		||||
#include <common/command.h>
 | 
			
		||||
@@ -178,6 +179,39 @@ static enum Result cmd_fan_set(void) {
 | 
			
		||||
    // Failed if fan not found
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
// Set a watchdog timer of 10 seconds
 | 
			
		||||
@@ -230,6 +264,12 @@ void smfi_event(void) {
 | 
			
		||||
            case CMD_FAN_SET:
 | 
			
		||||
                smfi_cmd[1] = cmd_fan_set();
 | 
			
		||||
                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__
 | 
			
		||||
            default:
 | 
			
		||||
                // Command not found
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,10 @@ enum Command {
 | 
			
		||||
    CMD_FAN_GET = 7,
 | 
			
		||||
    // Set fan speeds
 | 
			
		||||
    CMD_FAN_SET = 8,
 | 
			
		||||
    // Get keyboard map index
 | 
			
		||||
    CMD_KEYMAP_GET = 9,
 | 
			
		||||
    // Set keyboard map index
 | 
			
		||||
    CMD_KEYMAP_SET = 10,
 | 
			
		||||
    //TODO
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@ pub enum Cmd {
 | 
			
		||||
    Reset = 6,
 | 
			
		||||
    FanGet = 7,
 | 
			
		||||
    FanSet = 8,
 | 
			
		||||
    KeymapGet = 9,
 | 
			
		||||
    KeymapSet = 10,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub const CMD_SPI_FLAG_READ: u8 = 1 << 0;
 | 
			
		||||
@@ -195,6 +197,26 @@ impl<T: Timeout> Ec<T> {
 | 
			
		||||
        self.write(3, duty);
 | 
			
		||||
        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> {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										123
									
								
								tool/src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								tool/src/main.rs
									
									
									
									
									
								
							@@ -12,7 +12,7 @@ use std::{
 | 
			
		||||
    fs,
 | 
			
		||||
    io,
 | 
			
		||||
    process,
 | 
			
		||||
    str,
 | 
			
		||||
    str::{self, FromStr},
 | 
			
		||||
    time::{Duration, Instant},
 | 
			
		||||
    thread,
 | 
			
		||||
};
 | 
			
		||||
@@ -296,18 +296,64 @@ unsafe fn fan_set(index: u8, duty: u8) -> Result<(), Error> {
 | 
			
		||||
    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() {
 | 
			
		||||
    eprintln!("  console");
 | 
			
		||||
    eprintln!("  flash [file]");
 | 
			
		||||
    eprintln!("  flash_backup [file]");
 | 
			
		||||
    eprintln!("  fan [index] <duty>");
 | 
			
		||||
    eprintln!("  info");
 | 
			
		||||
    eprintln!("  keymap [layer] [output] [input] <value>");
 | 
			
		||||
    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() {
 | 
			
		||||
    let mut args = env::args().skip(1);
 | 
			
		||||
 | 
			
		||||
    match args.next() {
 | 
			
		||||
        Some(arg) => match arg.as_str() {
 | 
			
		||||
            "console" => match unsafe { console() } {
 | 
			
		||||
@@ -317,39 +363,25 @@ fn main() {
 | 
			
		||||
                    process::exit(1);
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            "fan" => match args.next() {
 | 
			
		||||
                Some(index_str) => match index_str.parse::<u8>() {
 | 
			
		||||
                    Ok(index) => match args.next() {
 | 
			
		||||
                        Some(duty_str) => match duty_str.parse::<u8>() {
 | 
			
		||||
                            Ok(duty) => match unsafe { fan_set(index, duty) } {
 | 
			
		||||
                                Ok(()) => (),
 | 
			
		||||
                                Err(err) => {
 | 
			
		||||
                                    eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
 | 
			
		||||
                                    process::exit(1);
 | 
			
		||||
                                },
 | 
			
		||||
                            },
 | 
			
		||||
                            Err(err) => {
 | 
			
		||||
                                eprintln!("failed to parse '{}': {:X?}", duty_str, err);
 | 
			
		||||
                                process::exit(1);
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        None => match unsafe { fan_get(index) } {
 | 
			
		||||
                            Ok(()) => (),
 | 
			
		||||
                            Err(err) => {
 | 
			
		||||
                                eprintln!("failed to get fan {}: {:X?}", index, err);
 | 
			
		||||
                                process::exit(1);
 | 
			
		||||
                            },
 | 
			
		||||
            "fan" => {
 | 
			
		||||
                let index = parse_arg(&mut args, "index");
 | 
			
		||||
                let duty_opt = parse_arg_opt(&mut args, "duty");
 | 
			
		||||
                match duty_opt {
 | 
			
		||||
                    Some(duty) => match unsafe { fan_set(index, duty) } {
 | 
			
		||||
                        Ok(()) => (),
 | 
			
		||||
                        Err(err) => {
 | 
			
		||||
                            eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
 | 
			
		||||
                            process::exit(1);
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(err) => {
 | 
			
		||||
                        eprintln!("failed to parse '{}': {:X?}", index_str, err);
 | 
			
		||||
                        process::exit(1);
 | 
			
		||||
                    None => match unsafe { fan_get(index) } {
 | 
			
		||||
                        Ok(()) => (),
 | 
			
		||||
                        Err(err) => {
 | 
			
		||||
                            eprintln!("failed to get fan {}: {:X?}", index, err);
 | 
			
		||||
                            process::exit(1);
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                None => {
 | 
			
		||||
                    eprintln!("no index provided");
 | 
			
		||||
                    process::exit(1);
 | 
			
		||||
                },
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "flash" => match args.next() {
 | 
			
		||||
                Some(path) => match unsafe { flash(&path, SpiTarget::Main) } {
 | 
			
		||||
@@ -384,6 +416,33 @@ fn main() {
 | 
			
		||||
                    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 {
 | 
			
		||||
                arg.push('\n');
 | 
			
		||||
                match unsafe { print(&arg.as_bytes()) } {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user