Expand description
Driver for a PS/2 PC keyboard.
Supports PS/2 Scan Code Set 1 and 2, on a variety of keyboard layouts. See the OSDev Wiki.
§Supports:
- Scancode Set 1 (from the i8042 PC keyboard controller)
- Scancode Set 2 (direct from the AT or PS/2 interface keyboard)
- Several keyboard layouts:
| Name | No. Keys | Description | Link |
|---|---|---|---|
Us104Key | 101/104 | North American standard English | Wikipedia |
Uk105Key | 102/105 | United Kingdom standard English | Wikipedia |
Azerty | 102/105 | Typically used in French locales | Wikipedia |
De105Key | 102/105 | German layout | Wikipedia |
FiSe105Key | 102/105 | Finnish/Swedish layout | Wikipedia |
No105Key | 102/105 | Norwegian layout | Wikipedia |
Jis109Key | 106/109 | JIS 109-key layout (Latin chars only) | Wikipedia |
Colemak | 101/104 | A keyboard layout designed to make typing more efficient and comfortable | Wikipedia |
Dvorak104Key | 101/104 | The more ‘ergonomic’ alternative to QWERTY | Wikipedia |
DVP104Key | 101/104 | Dvorak for Programmers | Wikipedia |
101/104 keys is ANSI layout (wide Enter key) and 102/105 keys is ISO layout (tall Enter key). The difference between 101 and 104 (and between 102 and 105) comes from the two Windows keys and the Menu key that were added when Windows 95 came out. JIS keyboards have extra keys, added by making the space-bar and backspace keys shorter.
§Usage
There are three basic steps to handling keyboard input. Your application may bypass some of these.
Ps2Decoder- converts 11-bit PS/2 words into bytes, removing the start/stop bits and checking the parity bits. Only needed if you talk to the PS/2 keyboard over GPIO pins and not required if you talk to the i8042 PC keyboard controller.ScancodeSet- converts from Scancode Set 1 (i8042 PC keyboard controller) or Scancode Set 2 (raw PS/2 keyboard output) into a symbolicKeyCodeand an up/downKeyState.EventDecoder- converts symbolicKeyCodeandKeyStateinto a Unicode characters (where possible) according to the currently selectedKeyboardLayout.
There is also PS2Keyboard which combines the above three functions into a
single object.
See the examples folder for more details.
§Keycodes
This crate uses symbolic keycodes to abstract over Scancode Set 1 and
Scancode Set 2. They represented by the KeyCode enum. The scancodes can
come from one of three supported physical keyboard layouts: 102/105 key
ISO, 101/104 key ANSI and 106/109-key JIS. Note that the symbolic
keycodes for letter keys are named after how the keys are used on a US or
UK English Keyboard. If you use a French AZERTY layout, the KeyCode::Q
key will produce the Unicode character 'A'.
§102/105 key ISO
This is the mapping of KeyCode to a 102/105-key ISO keyboard:
┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│
└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│
├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │
├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│
│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │
├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
│LShf│Oem5│ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │
├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │
│LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│
└─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘The 102-key is missing LWin, RWin, and Menu.
(Reference: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ISO105)
§101/104 key ANSI
This is the mapping of KeyCode to a 101/104-key ANSI keyboard:
┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│
└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│
├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Oem7 │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │
├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤ └────┴────┴────┘ ├────┼────┼────┤Num+│
│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│ Enter │ │Num4│Num5│Num6│ │
├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤ ┌────┐ ├────┼────┼────┼────┤
│ LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│ RShift │ │ Up │ │Num1│Num2│Num3│ │
├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │
│LCtrl│LWin │ Alt │ Space │AltGr│RWin │ Menu │RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│
└─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘Note that the Oem5 key is missing on the 104-key ANSI keyboard.
The 101-key is also missing LWin, RWin, and Menu.
(Reference: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ANSI104)
§106/109 key JIS
This is the mapping of KeyCode to a 106/109-key JIS keyboard:
┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
│Esc │ │ F1 │ F2 │ F3 │ F4 │ │ F5 │ F6 │ F7 │ F8 │ │ F9 │F10 │F11 │F12 │ │PrSc│Scrl│PBrk│
└────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
│Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Om13│BkSp│ │Inse│Home│PgUp│ │NumL│Num/│Num*│Num─│
├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
│ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │Oem4│Oem6│ Enter │ │Dele│End │PgDo│ │Num7│Num8│Num9│ │
├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤Num+│
│CapsLo│ A │ S │ D │ F │ G │ H │ J │ K │ L │Oem1│Oem3│Oem7│ │ │Num4│Num5│Num6│ │
├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
│LShift │ Z │ X │ C │ V │ B │ N │ M │OemC│OemP│Oem2│Oem12 │RShift │ │ Up │ │Num1│Num2│Num3│ │
├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤Num │
│LCtrl│LWin │LAlt │Oem9 │ Space Bar │Oem10│Oem11│RWin│Menu│RCtrl │ │Left│Down│Righ│ │Num0 │NumP│Ente│
└─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘Note that the Oem5 is missing on the 109-key JIS layout, but Oem9
(Muhenkan), Oem10 (Henkan/Zenkouho), Oem11
(Hiragana/Katakana), Oem12 (Backslash) and Oem13 (¥) are added.
The 106-key is missing LWin, RWin, and Menu.
(Reference: https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=OADG109A)
§Conversion Table
Scancode Set 1 and Scancode Set 2 can be losslessly converted. Indeed, this is what the i8042 keyboard controller in your PC does - it takes Scancode Set 2 from the keyboard and provides Scancode Set 1 to the Operating System. This allowed them to change the keyboard design without breaking compatibility with any MS-DOS applications that read raw scancodes from the keyboard.
This table shows the correspondence between our symbolic KeyCode, Scancode Set 1
and Scancode Set 2. Any codes prefixed 0xE0 or 0xE1 are extended multi-byte
scancodes. Typically these are keys that were not on the IBM PC and PC/XT
keyboards so they they were added in such a way that if you ignored the 0xE0,
you got a reasonable result anyway. For example ArrowLeft is 0xE04B in
Scancode Set 1 because Numpad4 is 0x4B and that was the left-arrow key on an
IBM PC or PC/XT.
| Symbolic Key | Scancode Set 1 | Scancode Set 2 | USB HID |
|---|---|---|---|
| Escape | 0x01 | 0x76 | 0x29 |
| F1 | 0x3B | 0x05 | 0x3A |
| F2 | 0x3C | 0x06 | 0x3B |
| F3 | 0x3D | 0x04 | 0x3C |
| F4 | 0x3E | 0x0C | 0x3D |
| F5 | 0x3F | 0x03 | 0x3E |
| F6 | 0x40 | 0x0B | 0x3F |
| F7 | 0x41 | 0x83 | 0x40 |
| F8 | 0x42 | 0x0A | 0x41 |
| F9 | 0x43 | 0x01 | 0x42 |
| F10 | 0x44 | 0x09 | 0x43 |
| F11 | 0x57 | 0x78 | 0x44 |
| F12 | 0x58 | 0x07 | 0x45 |
| PrintScreen | 0xE037 | 0xE07C | 0x46 |
| SysRq | 0x54 | 0x7F | – |
| ScrollLock | 0x46 | 0x7E | 0x47 |
| PauseBreak | – | – | 0x48 |
| - | – | – | – |
| Oem8 | 0x29 | 0x0E | 0x35 |
| Key1 | 0x02 | 0x16 | 0x1E |
| Key2 | 0x03 | 0x1E | 0x1F |
| Key3 | 0x04 | 0x26 | 0x20 |
| Key4 | 0x05 | 0x25 | 0x21 |
| Key5 | 0x06 | 0x2E | 0x22 |
| Key6 | 0x07 | 0x36 | 0x23 |
| Key7 | 0x08 | 0x3D | 0x24 |
| Key8 | 0x09 | 0x3E | 0x25 |
| Key9 | 0x0A | 0x46 | 0x26 |
| Key0 | 0x0B | 0x45 | 0x27 |
| OemMinus | 0x0C | 0x4E | 0x2D |
| OemPlus | 0x0D | 0x55 | 0x2E |
| Backspace | 0x0E | 0x66 | 0x2A |
| Insert | 0xE052 | 0xE070 | 0x49 |
| Home | 0xE047 | 0xE06C | 0x4A |
| PageUp | 0xE049 | 0xE07D | 0x4B |
| NumpadLock | 0x45 | 0x77 | 0x53 |
| NumpadDivide | 0xE035 | 0xE04A | 0x54 |
| NumpadMultiply | 0x37 | 0x7C | 0x55 |
| NumpadSubtract | 0x4A | 0x7B | 0x56 |
| - | – | – | – |
| Tab | 0x0F | 0x0D | 0x2B |
| Q | 0x10 | 0x15 | 0x14 |
| W | 0x11 | 0x1D | 0x1A |
| E | 0x12 | 0x24 | 0x08 |
| R | 0x13 | 0x2D | 0x15 |
| T | 0x14 | 0x2C | 0x17 |
| Y | 0x15 | 0x35 | 0x1C |
| U | 0x16 | 0x3C | 0x18 |
| I | 0x17 | 0x43 | 0x0C |
| O | 0x18 | 0x44 | 0x12 |
| P | 0x19 | 0x4D | 0x13 |
| Oem4 | 0x1A | 0x54 | 0x2F |
| Oem6 | 0x1B | 0x5B | 0x30 |
| Oem5 | 0x56 | 0x61 | 0x64 |
| Oem7 | 0x2B | 0x5D | 0x31 |
| Delete | 0xE053 | 0xE071 | 0x4C |
| End | 0xE04F | 0xE069 | 0x4D |
| PageDown | 0xE051 | 0xE07A | 0x4E |
| Numpad7 | 0x47 | 0x6C | 0x5F |
| Numpad8 | 0x48 | 0x75 | 0x60 |
| Numpad9 | 0x49 | 0x7D | 0x61 |
| NumpadAdd | 0x4E | 0x79 | 0x57 |
| - | – | – | – |
| CapsLock | 0x3A | 0x58 | 0x39 |
| A | 0x1E | 0x1C | 0x04 |
| S | 0x1F | 0x1B | 0x16 |
| D | 0x20 | 0x23 | 0x07 |
| F | 0x21 | 0x2B | 0x09 |
| G | 0x22 | 0x34 | 0x0A |
| H | 0x23 | 0x33 | 0x0B |
| J | 0x24 | 0x3B | 0x0D |
| K | 0x25 | 0x42 | 0x0E |
| L | 0x26 | 0x4B | 0x0F |
| Oem1 | 0x27 | 0x4C | 0x33 |
| Oem3 | 0x28 | 0x52 | 0x34 |
| Return | 0x1C | 0x5A | 0x28 |
| Numpad4 | 0x4B | 0x6B | 0x5C |
| Numpad5 | 0x4C | 0x73 | 0x5D |
| Numpad6 | 0x4D | 0x74 | 0x5E |
| - | – | – | – |
| LShift | 0x2A | 0x12 | 0xE1 |
| Z | 0x2C | 0x1A | 0x1D |
| X | 0x2D | 0x22 | 0x1B |
| C | 0x2E | 0x21 | 0x06 |
| V | 0x2F | 0x2A | 0x19 |
| B | 0x30 | 0x32 | 0x05 |
| N | 0x31 | 0x31 | 0x11 |
| M | 0x32 | 0x3A | 0x10 |
| OemComma | 0x33 | 0x41 | 0x36 |
| OemPeriod | 0x34 | 0x49 | 0x37 |
| Oem2 | 0x35 | 0x4A | 0x38 |
| RShift | 0x36 | 0x59 | 0xE5 |
| ArrowUp | 0xE048 | 0xE075 | 0x52 |
| Numpad1 | 0x4F | 0x69 | 0x59 |
| Numpad2 | 0x50 | 0x72 | 0x5A |
| Numpad3 | 0x51 | 0x7A | 0x5B |
| NumpadEnter | 0xE01C | 0xE075 | 0x58 |
| - | – | – | – |
| LControl | 0x1D | 0x14 | 0xE0 |
| LWin | 0xE05B | 0xE01F | 0xE3 |
| LAlt | 0x38 | 0x11 | 0xE2 |
| Spacebar | 0x39 | 0x29 | 0x2C |
| RAltGr | 0xE038 | 0xE011 | 0xE6 |
| RWin | 0xE05C | 0xE027 | 0xE7 |
| Apps | 0xE05C | 0xE02F | 0x65 |
| RControl | 0xE01D | 0xE014 | 0xE4 |
| ArrowLeft | 0xE04B | 0xE06B | 0x50 |
| ArrowDown | 0xE050 | 0xE072 | 0x51 |
| ArrowRight | 0xE04D | 0xE074 | 0x52 |
| Numpad0 | 0x52 | 0x70 | 0x62 |
| NumpadPeriod | 0x53 | 0x71 | 0x63 |
| - | – | – | – |
| Oem9 | 0x7B | 0x67 | ?? |
| Oem10 | 0x79 | 0x64 | ?? |
| Oem11 | 0x70 | 0x13 | ?? |
| Oem12 | 0x73 | 0x51 | ?? |
| Oem13 | 0x7D | 0x6A | ?? |
| - | – | – | ?? |
| PrevTrack | 0xE010 | 0xE015 | ?? |
| NextTrack | 0xE019 | 0xE04D | ?? |
| Mute | 0xE020 | 0xE023 | ?? |
| Calculator | 0xE021 | 0xE02B | ?? |
| Play | 0xE022 | 0xE034 | ?? |
| Stop | 0xE024 | 0xE03B | ?? |
| VolumeDown | 0xE02E | 0xE021 | ?? |
| VolumeUp | 0xE030 | 0xE032 | ?? |
| WWWHome | 0xE032 | 0xE03A | ?? |
| TooManyKeys | – | 0x00 | ?? |
| PowerOnTestOk | – | 0xAA | ?? |
| RControl2 | 0xE11D | 0xE114 | ?? |
| RAlt2 | 0xE02A | 0xE012 | ?? |
Note 1: PauseBreak does not have a scancode because it’s something we infer from a
sequence of other keypresses (NumLock with RControl2 held).
Note 2: SysReq doesn’t have a key on the diagram, because the scancode is
only generated when you do Alt + PrintScreen.
Modules§
- layouts
- Implements the various keyboard layouts.
Structs§
- Event
Decoder - Converts KeyEvents into Unicode, according to the current Keyboard Layout
- KeyEvent
- A event describing something happen to a key on your keyboard.
- Modifiers
- The set of modifier keys you have on a keyboard.
- PS2Keyboard
- Encapsulates decode/sampling logic, and handles state transitions and key events for PS/2 Keyboards
- Ps2Decoder
- Handles decoding of IBM PS/2 Keyboard (and IBM PC/AT Keyboard) bit-streams.
- Scancode
Set1 - Contains the implementation of Scancode Set 1.
- Scancode
Set2 - Contains the implementation of Scancode Set 2.
- UsbBoot
Keyboard Report - A USB HID report as received from a keyboard in Boot Mode
- UsbDecoded
KeyIter - An Iterator that produces [‘DecodedKey’] values, using an
EventDecoder - UsbKey
Event Iter - An Iterator that produces [‘KeyEvent’] values
- UsbKeyboard
- Encapsulates HID frame handling, and handles state transitions and key events for USB HID Keyboards
Enums§
- Decoded
Key - Contains either a Unicode character, or a raw key code.
- Error
- Indicates different error conditions.
- Handle
Control - Options for how we can handle what happens when the Ctrl key is held down and a letter is pressed.
- KeyCode
- Keycodes that can be generated by a keyboard.
- KeyState
- The new state for a key, as part of a key event.
- Physical
Keyboard - Describes a physical keyboard
- UsbModifiers
Traits§
- Keyboard
Layout - Describes a Keyboard Layout.
- Scancode
Set - A mechanism to convert bytes from a Keyboard into
KeyCodevalues.