Skip to content

Commit 1b11ccc

Browse files
committed
Fix broken scan code set 2 decoding.
) Re-worked scan code state machines. ) Moved code logic into scan-code objects. ) Fix Backslash/HashTilde mixup (as tested on my UK Dell SK-1000REW)
1 parent 5406957 commit 1b11ccc

File tree

3 files changed

+181
-71
lines changed

3 files changed

+181
-71
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pc-keyboard"
3-
version = "0.3.1"
3+
version = "0.4.0"
44
authors = ["Jonathan 'theJPster' Pallant <[email protected]>"]
55
description = "PS/2 keyboard interface library. Handles UK 105-key keyboards producing Scancode Set 2."
66
keywords = ["arm", "cortex-m", "template", "video", "menu"]

src/lib.rs

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,8 @@ pub trait KeyboardLayout {
205205
}
206206

207207
pub trait ScancodeSet {
208-
/// Handles state logic based on the byte.
209-
/// `ConsumeState::Consume(state)` indicates that the byte is now consumed and
210-
/// there may or may not be a new state.
211-
///
212-
/// `ConsumeState::Proceed(state)` indicates that the byte should be passed to
213-
/// the map methods, and there may or may not be a new state.
214-
fn advance_state(state: DecodeState, code: u8) -> Result<ConsumeState, Error>;
208+
/// Handles the state logic for the decoding of scan codes into key events.
209+
fn advance_state(state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error>;
215210

216211
/// Convert a Scan Code set X byte to our 'KeyCode' enum
217212
fn map_scancode(code: u8) -> Result<KeyCode, Error>;
@@ -221,21 +216,6 @@ pub trait ScancodeSet {
221216
fn map_extended_scancode(code: u8) -> Result<KeyCode, Error>;
222217
}
223218

224-
pub enum ConsumeState {
225-
Consume(DecodeState),
226-
Proceed(DecodeState),
227-
}
228-
229-
impl ConsumeState {
230-
/// Allocates a new decode state
231-
fn extract_state(&self) -> DecodeState {
232-
match self {
233-
&ConsumeState::Consume(ref st) => st.clone(),
234-
&ConsumeState::Proceed(ref st) => st.clone(),
235-
}
236-
}
237-
}
238-
239219
#[derive(Debug)]
240220
pub struct Modifiers {
241221
pub lshift: bool,
@@ -338,31 +318,8 @@ where
338318
/// We assume the start, stop and parity bits have been processed and
339319
/// verified.
340320
pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
341-
let st = self.decode_state;
342-
self.clear();
343-
let consume_state = S::advance_state(st, byte)?;
344-
self.decode_state = consume_state.extract_state();
345-
match consume_state {
346-
ConsumeState::Consume(_) => Ok(None),
347-
ConsumeState::Proceed(st) => match st {
348-
DecodeState::Start => {
349-
let code = S::map_scancode(byte)?;
350-
Ok(Some(KeyEvent::new(code, KeyState::Down)))
351-
}
352-
DecodeState::Extended => {
353-
let code = S::map_extended_scancode(byte)?;
354-
Ok(Some(KeyEvent::new(code, KeyState::Down)))
355-
}
356-
DecodeState::Release => {
357-
let code = S::map_scancode(byte)?;
358-
Ok(Some(KeyEvent::new(code, KeyState::Up)))
359-
}
360-
DecodeState::ExtendedRelease => {
361-
let code = S::map_extended_scancode(byte)?;
362-
Ok(Some(KeyEvent::new(code, KeyState::Up)))
363-
}
364-
},
365-
}
321+
let r = S::advance_state(&mut self.decode_state, byte);
322+
r
366323
}
367324

368325
/// Shift a bit into the register.
@@ -374,6 +331,8 @@ where
374331
self.num_bits += 1;
375332
if self.num_bits == KEYCODE_BITS {
376333
let word = self.register;
334+
self.register = 0;
335+
self.num_bits = 0;
377336
self.add_word(word)
378337
} else {
379338
Ok(None)
@@ -791,8 +750,8 @@ mod test {
791750
}
792751
codes.sort();
793752
println!("{:?}", codes);
794-
assert_eq!(codes.len(), 85);
795-
assert_eq!(errs.len(), 171);
753+
assert_eq!(codes.len(), 86);
754+
assert_eq!(errs.len(), 170);
796755
}
797756

798757
#[test]
@@ -811,6 +770,69 @@ mod test {
811770
Ok(Some(KeyEvent::new(KeyCode::S, KeyState::Down)))
812771
);
813772
}
773+
774+
#[test]
775+
fn test_set_1_ext_down_up_down() {
776+
let mut k = Keyboard::new(layouts::Us104Key, ScancodeSet1);
777+
assert_eq!(k.add_byte(0xe0), Ok(None));
778+
assert_eq!(
779+
k.add_byte(0x1c),
780+
Ok(Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Down)))
781+
);
782+
assert_eq!(k.add_byte(0xe0), Ok(None));
783+
assert_eq!(
784+
k.add_byte(0x9c),
785+
Ok(Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Up)))
786+
);
787+
}
788+
789+
#[test]
790+
fn test_set_2_down_up() {
791+
let mut k = Keyboard::new(layouts::Us104Key, ScancodeSet2);
792+
assert_eq!(
793+
k.add_byte(0x29),
794+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down)))
795+
);
796+
assert_eq!(k.add_byte(0xF0), Ok(None));
797+
assert_eq!(
798+
k.add_byte(0x29),
799+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up)))
800+
);
801+
assert_eq!(
802+
k.add_byte(0x29),
803+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down)))
804+
);
805+
assert_eq!(k.add_byte(0xF0), Ok(None));
806+
assert_eq!(
807+
k.add_byte(0x29),
808+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up)))
809+
);
810+
assert_eq!(
811+
k.add_byte(0x29),
812+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down)))
813+
);
814+
assert_eq!(k.add_byte(0xF0), Ok(None));
815+
assert_eq!(
816+
k.add_byte(0x29),
817+
Ok(Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up)))
818+
);
819+
}
820+
821+
#[test]
822+
fn test_set_2_ext_down_up() {
823+
let mut k = Keyboard::new(layouts::Us104Key, ScancodeSet2);
824+
assert_eq!(k.add_byte(0xE0), Ok(None));
825+
assert_eq!(
826+
k.add_byte(0x6C),
827+
Ok(Some(KeyEvent::new(KeyCode::Home, KeyState::Down)))
828+
);
829+
assert_eq!(k.add_byte(0xE0), Ok(None));
830+
assert_eq!(k.add_byte(0xF0), Ok(None));
831+
assert_eq!(
832+
k.add_byte(0x6C),
833+
Ok(Some(KeyEvent::new(KeyCode::Home, KeyState::Up)))
834+
);
835+
}
814836
}
815837

816838
// ****************************************************************************

src/scancodes.rs

Lines changed: 109 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{
2-
ConsumeState, DecodeState, Error, KeyCode, ScancodeSet, EXTENDED_KEY_CODE, KEY_RELEASE_CODE,
2+
DecodeState, Error, KeyCode, KeyEvent, KeyState, ScancodeSet, EXTENDED_KEY_CODE,
3+
KEY_RELEASE_CODE,
34
};
45

56
/// Contains the implementation of Scancode Set 1.
@@ -8,19 +9,62 @@ pub struct ScancodeSet1;
89

910
impl ScancodeSet for ScancodeSet1 {
1011
/// Implements state logic for scancode set 1
11-
fn advance_state(state: DecodeState, code: u8) -> Result<ConsumeState, Error> {
12-
match state {
13-
DecodeState::Start | DecodeState::Release | DecodeState::ExtendedRelease => {
12+
///
13+
/// Start:
14+
/// E0 => Extended
15+
/// >= 0x80 => Key Up
16+
/// <= 0x7F => Key Down
17+
///
18+
/// Extended:
19+
/// >= 0x80 => Extended Key Up
20+
/// <= 0x7F => Extended Key Down
21+
fn advance_state(state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
22+
match *state {
23+
DecodeState::Start => {
1424
match code {
15-
EXTENDED_KEY_CODE => Ok(ConsumeState::Consume(DecodeState::Extended)),
16-
0x81..=0xD8 => Ok(ConsumeState::Proceed(DecodeState::Release)),
17-
_ => Ok(ConsumeState::Proceed(DecodeState::Start)),
25+
EXTENDED_KEY_CODE => {
26+
*state = DecodeState::Extended;
27+
Ok(None)
28+
}
29+
0x80..=0xFF => {
30+
// Release codes
31+
Ok(Some(KeyEvent::new(
32+
Self::map_scancode(code - 0x80)?,
33+
KeyState::Up,
34+
)))
35+
}
36+
_ => {
37+
// Normal codes
38+
Ok(Some(KeyEvent::new(
39+
Self::map_scancode(code)?,
40+
KeyState::Down,
41+
)))
42+
}
1843
}
1944
}
20-
DecodeState::Extended => match code {
21-
0x90..=0xED => Ok(ConsumeState::Proceed(DecodeState::ExtendedRelease)),
22-
_ => Ok(ConsumeState::Proceed(DecodeState::Extended)),
23-
},
45+
DecodeState::Extended => {
46+
*state = DecodeState::Start;
47+
match code {
48+
0x80..=0xFF => {
49+
// Extended Release codes
50+
Ok(Some(KeyEvent::new(
51+
Self::map_extended_scancode(code - 0x80)?,
52+
KeyState::Up,
53+
)))
54+
}
55+
_ => {
56+
// Normal release codes
57+
Ok(Some(KeyEvent::new(
58+
Self::map_extended_scancode(code)?,
59+
KeyState::Down,
60+
)))
61+
}
62+
}
63+
}
64+
_ => {
65+
// Can't get in to this state
66+
unimplemented!();
67+
}
2468
}
2569
}
2670

@@ -203,21 +247,64 @@ pub struct ScancodeSet2;
203247

204248
impl ScancodeSet for ScancodeSet2 {
205249
/// Implements state logic for scancode set 2
206-
fn advance_state(state: DecodeState, code: u8) -> Result<ConsumeState, Error> {
207-
match state {
250+
///
251+
/// Start:
252+
/// F0 => Release
253+
/// E0 => Extended
254+
/// xx => Key Down
255+
///
256+
/// Release:
257+
/// xxx => Key Up
258+
///
259+
/// Extended:
260+
/// F0 => Release Extended
261+
/// xx => Extended Key Down
262+
///
263+
/// Release Extended:
264+
/// xxx => Extended Key Up
265+
fn advance_state(state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
266+
match *state {
208267
DecodeState::Start => match code {
209-
EXTENDED_KEY_CODE => Ok(ConsumeState::Consume(DecodeState::Extended)),
210-
KEY_RELEASE_CODE => Ok(ConsumeState::Consume(DecodeState::Release)),
211-
_ => Ok(ConsumeState::Proceed(DecodeState::Start)),
268+
EXTENDED_KEY_CODE => {
269+
*state = DecodeState::Extended;
270+
Ok(None)
271+
}
272+
KEY_RELEASE_CODE => {
273+
*state = DecodeState::Release;
274+
Ok(None)
275+
}
276+
_ => Ok(Some(KeyEvent::new(
277+
Self::map_scancode(code)?,
278+
KeyState::Down,
279+
))),
212280
},
281+
DecodeState::Release => {
282+
*state = DecodeState::Start;
283+
Ok(Some(KeyEvent::new(Self::map_scancode(code)?, KeyState::Up)))
284+
}
213285
DecodeState::Extended => match code {
214-
KEY_RELEASE_CODE => Ok(ConsumeState::Consume(DecodeState::ExtendedRelease)),
215-
_ => Ok(ConsumeState::Proceed(DecodeState::Extended)),
286+
KEY_RELEASE_CODE => {
287+
*state = DecodeState::ExtendedRelease;
288+
Ok(None)
289+
}
290+
_ => {
291+
*state = DecodeState::Start;
292+
Ok(Some(KeyEvent::new(
293+
Self::map_extended_scancode(code)?,
294+
KeyState::Down,
295+
)))
296+
}
216297
},
217-
DecodeState::Release => Ok(ConsumeState::Proceed(DecodeState::Release)),
218-
DecodeState::ExtendedRelease => Ok(ConsumeState::Proceed(DecodeState::ExtendedRelease)),
298+
DecodeState::ExtendedRelease => {
299+
*state = DecodeState::Start;
300+
Ok(Some(KeyEvent::new(
301+
Self::map_extended_scancode(code)?,
302+
KeyState::Up,
303+
)))
304+
}
219305
}
220306
}
307+
221308
/// Implements the single byte codes for Set 2.
222309
fn map_scancode(code: u8) -> Result<KeyCode, Error> {
223310
match code {
@@ -285,7 +372,8 @@ impl ScancodeSet for ScancodeSet2 {
285372
0x59 => Ok(KeyCode::ShiftRight), // 59
286373
0x5A => Ok(KeyCode::Enter), // 5A
287374
0x5B => Ok(KeyCode::BracketSquareRight), // 5B
288-
0x5D => Ok(KeyCode::BackSlash), // 5D
375+
0x5D => Ok(KeyCode::HashTilde), // 5D
376+
0x61 => Ok(KeyCode::BackSlash), // 61
289377
0x66 => Ok(KeyCode::Backspace), // 66
290378
0x69 => Ok(KeyCode::Numpad1), // 69
291379
0x6B => Ok(KeyCode::Numpad4), // 6B

0 commit comments

Comments
 (0)