PS/2 Keyboard: Difference between revisions

The keyboard reset transaction was not clear, the reset function does return ACK before the test result
[unchecked revision][unchecked revision]
No edit summary
(The keyboard reset transaction was not clear, the reset function does return ACK before the test result)
 
(25 intermediate revisions by 11 users not shown)
Line 62:
| Set scan code set 3
|}
| Get/set current scan code set
| 0xFA (ACK) or 0xFE (Resend) if scan code is being set; 0xFA (ACK) then the scan code set number, or 0xFE (Resend) if you're getting the scancode. If getting the scancode the table indicates the value that identify each set:
{| {{wikitable}}
|-
! Value
! Use
|-
| 43
| Scan code set 1
|-
| 41
| Scan code set 2
|-
| 3f
| Scan code set 3
|}
 
|-
| 0xF2
| None
| Identify keyboard
| 0xFA (ACK) followed by none or more ID bytes (see [[http:"8042" PS//wiki.osdev.org/%228042%22_PS/2_Controller2 Controller#Detecting_PSDetecting PS.2F2_Device_Types2F2 Device Types| "Detecting Device Types"]])
|-
| 0xF3
Line 148 ⟶ 163:
| None
| Reset and start self-test
| 0xFA (ACK) or 0xFE (Resend) followed by 0xAA (self-test passed), 0xFC or 0xFD (self test failed), or 0xFE (Resend)
|}
 
Line 224 ⟶ 239:
* Various other key states (shift, alt, control, etc)
* Various "toggle" states (CapsLock, ScrollLock, NumberLock, etc)
 
== Enough, give me code! ==
 
So, first read the scan code set table, and now start to code. If you too lazy, there's a full code:
 
(inb/outb can be found here: [[Inline Assembly/Examples#I.2FO access|Inline Assembly Examples - I/O Access]])
<source lang="c">
/*
PS/2 keyboard code.
Dependencies:
inb function and scancode table.
*/
char getScancode() {
char c=0;
do {
if(inb(0x60)!=c) {
c=inb(0x60);
if(c>0)
return c;
}
} while(1);
}
 
char getchar() {
return scancode[getScancode()+1];
}
</source>
 
== Scan Code Sets ==
Line 277 ⟶ 265:
The following table shows which scan codes correspond to which keys when using scan code set 1 (for a "US QWERTY" keyboard only):
 
Note that scancodes with extended byte (E0) generates two different interrupts: the first containing the E0 byte, the second containing the scancode
{| {{wikitable}}
|-
Line 700 ⟶ 689:
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0x10
| (multimedia) previous track pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0x19
| style="background: #E8E8E8" | (multimedia) next track pressed
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
Line 710 ⟶ 717:
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0x20
| (multimedia) mute pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x21
| style="background: #E8E8E8" | (multimedia) calculator pressed
| align="right" | 0xE0, 0x22
| (multimedia) play pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0x24
| (multimedia) stop pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
| align="right" | 0xE0, 0x2E
| (multimedia) volume down pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0x30
| (multimedia) volume up pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
| align="right" | 0xE0, 0x32
| (multimedia) WWW home pressed
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
Line 778 ⟶ 821:
| style="background: #E8E8E8" align="right" | 0xE0, 0x5D
| style="background: #E8E8E8" | "apps" pressed
| align="right" | 0xE0, 0x5E
| (ACPI) power pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x5F
| style="background: #E8E8E8" | (ACPI) sleep pressed
|-
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0x63
| style="background: #E8E8E8" | (ACPI) wake pressed
|-
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0x65
| style="background: #E8E8E8" | (multimedia) WWW search pressed
| align="right" | 0xE0, 0x66
| (multimedia) WWW favorites pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x67
| style="background: #E8E8E8" | (multimedia) WWW refresh pressed
|-
| align="right" | 0xE0, 0x68
| (multimedia) WWW stop pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x69
| style="background: #E8E8E8" | (multimedia) WWW forward pressed
| align="right" | 0xE0, 0x6A
| (multimedia) WWW back pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x6B
| style="background: #E8E8E8" | (multimedia) my computer pressed
|-
| align="right" | 0xE0, 0x6C
| (multimedia) email pressed
| style="background: #E8E8E8" align="right" | 0xE0, 0x6D
| style="background: #E8E8E8" | (multimedia) media select pressed
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0x90
| (multimedia) previous track released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0x99
| style="background: #E8E8E8" | (multimedia) next track released
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
Line 791 ⟶ 888:
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0xA0
| (multimedia) mute released
| style="background: #E8E8E8" align="right" | 0xE0, 0xA1
| style="background: #E8E8E8" | (multimedia) calculator released
| align="right" | 0xE0, 0xA2
| (multimedia) play released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0xA4
| (multimedia) stop released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
| align="right" | 0xE0, 0xAE
| (multimedia) volume down released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
| align="right" | 0xE0, 0xB0
| (multimedia) volume up released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
| align="right" | 0xE0, 0xB2
| (multimedia) WWW home released
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
Line 859 ⟶ 992:
| style="background: #E8E8E8" align="right" | 0xE0, 0xDD
| style="background: #E8E8E8" | "apps" released
| align="right" | 0xE0, 0xDE
| (ACPI) power released
| style="background: #E8E8E8" align="right" | 0xE0, 0xDF
| style="background: #E8E8E8" | (ACPI) sleep released
|-
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0xE3
| style="background: #E8E8E8" | (ACPI) wake released
|-
|
|
| style="background: #E8E8E8" align="right" | 0xE0, 0xE5
| style="background: #E8E8E8" | (multimedia) WWW search released
| align="right" | 0xE0, 0xE6
| (multimedia) WWW favorites released
| style="background: #E8E8E8" align="right" | 0xE0, 0xE7
| style="background: #E8E8E8" | (multimedia) WWW refresh released
|-
| align="right" | 0xE0, 0xE8
| (multimedia) WWW stop released
| style="background: #E8E8E8" align="right" | 0xE0, 0xE9
| style="background: #E8E8E8" | (multimedia) WWW forward released
| align="right" | 0xE0, 0xEA
| (multimedia) WWW back released
| style="background: #E8E8E8" align="right" | 0xE0, 0xEB
| style="background: #E8E8E8" | (multimedia) my computer released
|-
| align="right" | 0xE0, 0xEC
| (multimedia) email released
| style="background: #E8E8E8" align="right" | 0xE0, 0xED
| style="background: #E8E8E8" | (multimedia) media select released
|
|
| style="background: #E8E8E8" |
| style="background: #E8E8E8" |
|-
|
|
Line 894 ⟶ 1,063:
 
Note: There is no scan code for "pause key released" (it behaves as if it is released as soon as it's pressed)
 
 
=== Scan Code Set 2 ===
Line 1,971 ⟶ 2,139:
The following table shows which scan codes correspond to which keys when using scan code set 3 (for a "US QWERTY" keyboard only):
 
{| {{wikitable}}
[http://www.computer-engineering.org/ps2keyboard/scancodes3.html Scan Codes]
|-
 
!Key
'''TODO'''
!Code for Scan code set 3
 
|-
|A || 1C
|-
|B || 32
|-
|C || 21
|-
|D || 23
|-
|E || 24
|-
|F || 2B
|-
|G || 34
|-
|H || 33
|-
|I || 43
|-
|J || 3B
|-
|K || 42
|-
|L || 4B
|-
|M || 3A
|-
|N || 31
|-
|O || 44
|-
|P || 4D
|-
|Q || 15
|-
|R || 2D
|-
|S || 1B
|-
|T || 2C
|-
|U || 3C
|-
|V || 2A
|-
|W || 1D
|-
|X || 22
|-
|Y || 35
|-
|Z || 1A
|}
 
[https://web.archive.org/web/20170108131104/http://www.computer-engineering.org/ps2keyboard/scancodes3.html Scan code]
 
==See Also==
Line 1,993 ⟶ 2,215:
 
===External Links===
*[http://www.computer-engineering.org www.Computer-Engineering.org]
*[http://www.webmasteren.eu/viden/os/PS2.pdf KMT dk's ps2 keyboard and controller referance]
*[http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html Keyboard scancodes] - A complete reference on all scancodes you might encounter.
*[https://web.archive.org/web/20030621203107/http://www.microsoft.com/whdc/hwdev/tech/input/Scancode.mspx USB HID to PS/2 Translation Table] - Microsoft's table of scancodes and USB equivalents
*[https://web.archive.org/web/20190301075756/http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc Keyboard Scan Code Specification] - Microsoft's specification for scancodes
*[https://www.youtube.com/playlist?list=PLUZozxlhse-NUto5JeJ0EDXEUFloWBdAj PS/2 keyboard interface playlist] - A video playlist of building a PS/2 keyboard interface on bread boards, by Ben Eater.
 
==== Implementations ====
* [http://lxr.linux.no/#linux+v3.5.4/drivers/input/keyboard/atkbd.c Linux] (C,GPL)
* [https://github.com/minix3Stichting-MINIX-Research-Foundation/minix/blob/e1131d9c96fe00bd07aa66540e0830a91dbbf31emaster/minix/drivers/hid/pckbd/pckbd.c Minix]
 
[[Category:Human Interface Device]]
Anonymous user