Home and Links
 Your PC and Security
 Server NAS
 DVD making
 Raspberry Pi
 PIC projects
 Other projects
 Next >>

PS2 Keyboard to serial converter


This page still 'Under construction'

PS/2 Keyboard protocol

Unfortunately, the PS2 Keyboard does not use standard 'RS232' protocols - so you will have to use 'bit banging' to 'talk' to the Keyboard. However the good news is that many PIC's - even low end ones - now come with built-in Serial communication circuits, so the serial 'up link' (to the Raspberry Pi) will be a lot easier to code.

Another problem with the PS/2 keyboard is that it doesn't send ascii codes = instead it sends 'key scan codes'. However there are only about 102 keys, so 'looking up' the ASCII code is 'easy enough' (using a 102 instruction Look-Ip-Table)

Almost any low-end PIC will do the trick. Two pins are needed to communicate with the Keyboard (Data and Clock) and one to send data to the Pi (TxD). So even the smallest PIC should be sufficient - such as the 10F206 which runs at 4 HMz (1 MIPS), and has 512 instructions space, 24 registers, one 8 bit timer/counter and one comparator. Both SOT and DIL version have 3 i/o pins and 1 input only (on the 8pin DIL package, 2 pins are unused)

The keyboard data rate will be somewhere between 10 and 16 kHz, whilst the Pi serial in will be 9600 baud (i.e. 9.6 kHz). 'Bit banging' with a 1MIPS PIC means we will have at least 62 instructions to process each bit.
Using a more powerful PIC - for example one with built in UART - is thus 'over kill', but might well make the project easier to code. In theory, it would even be possible to use a PIC with USB capability as a 'PS2 to USB converter' ..

The protocols used by the PS/2 keyboard are the ones defined for the AT (NOT the 'XT', which is totally different). Any keyboard with a mini-DIN will be PS/2 AT type (the old XT version used the chunky standard DIN plug).

To connect to the PS/2 keyboard you need a 6 pin mini-DIN socket. The socket front view (notch and tab [] to the top) pin numbers are :-
  6 [] 5 4       3   2  1 p1 Data, /RTS (bi-directional, open-collector) p2 (mouse Data, on dual cable) p3 Gnd p4 +5v (275mA) from PC (to power the Keyboard/Mouse) p5 Clock, CTS (bi-directional, open-collector) = the PC can thus inhibit KB: Tx by holding Clk Lo p6 (mouse Clk, on dual cable)
Data is 'clcoked' and sent at 10-16 kHz, 12 bits per packet = 1 start bit, 8 data bits (LSB first), 1 parity bit (odd), 1 ACK (from the receiver), 1 stop bit.
Both Data and Clk lines are 'open collector'. The interface is 'bi-directional'. The PC uses the Clk line to 'throttle' data transmission - by holding ther Clk lone Lo - however the Keyboard always generates the Clk.
To read data, the PC allows the Clk to float Hi - the Keyboard then Clk's the data out.
When the PC wants to send a byte to the keyboard, it pulls the data line Lo before releasing the Clk  (i.e. lets the Clk line go Hi). The KB responds by 'clocking the data in'.
If you're lucky, the keyboard isn't deciding to transmit at the same time the PC pulls the data line Lo, it responds by issuing 10 clock pulses (at about 10,000 baud) on the CLK line and the computer then uses those clock transitions to shift out a 'frame' on TxD on rising clock edges.  The frame format is 1 start bit, 8 data bits and 1 odd parity bit.
NOTE The keyboard sees the PC holding the Data lo as the start bit, so PC places the first data bit on TxD when it sees the first clock rising (Lo-Hi) edge.
To avoid 'loosing' a kay press, the PIC holds the keyboard Clk Lo when sending ascii codes to the Pi.
PC Commands (sent to the keyboard) :-
ED, 00-07 = Set LED's, bit 0 is Scroll lock, bit 1 is Num lock, bit 2 is Caps lock (so ED 07 will activate all 3 LEDS, ED 00 will turn all 3 off) EE = 'Echo', instructs the Keyboard to send back '0xEE' (for testing?) F0, 01/02/03 = Select mode (1, 2 or 3) F2 = Send ID (the keyboard transmits it's I.D.) F3, 0ddbbaaa = Set dd repeat delay and aaa rate (delay is (dd+1)*250 msec, rate is (8+aaa)*2^bb*4 msec) F4 = Clear key buffer F5 = Reset to default and wait for 'enable' F6 = Reset to default settings FA = Acknowledge FE = Error, resend latst key (causes the Keyboard to retransmit) FF = Reset keyboard
Status codes sent by Keyvboard to PC
00 = Buffer overflow AA = Self-test passed F0 = Release code FA = Acknowledge last command FD = Self-test failed FC = Self-test failed FE = Last command in error; re-send E0 = scan/release code
The computer and keyboard must acknowledge each command and key code with either FA if there was no error, or FE if the last command/key-code should be re-sent.

When the PS/2 was introduced, the keyboard supported 3 'modes' (the mode was typically set by a switch on the back of keyboard).

In mode 1, the keyboard acted like the ancient XT keyboard and issued XT scan-codes.  The keyboard handled the cursor keypad (which didn't exist on the XT) by simulating pressing or releasing a shift key (depending on whether shift or num-lock are pressed) and then sending codes from the numeric keypad.
Mode 2 was 'XT+' i.e. the same as mode 1, except that when the numeric keypad codes are issued it prefixes everything with E0 (and the release codes are the scan-codes prefixed with F0).
In mode 3, each key gets a unique code and the release are the scan-codes prefixed by F0 (as in m2).
Later IBM PS/2 keyboards (and all clones) dispensed with the switch and operated in mode 3.
When the AT keyboard is first reset it's supposed to send an AA if its self-test passed or FD or FC if it failed.  But before it does this, it sends a continual stream of AAs with the parity incorrect.  Once the computer sends an FE to indicate that there is a parity error, the keyboard stops sending bad AAs and sends a correct AA or an FD or FC
If this sounds to you like someone made a 'quick fix' in the keyboard firmware to cope with mis-matched reset timing (the keyboard always finishes resetting before the computer so the computer could miss the AA/FD/FC) you would be thinking just like me ....
NOTE that the keyboard always sends 'key scan codes', not ASCII character codes ! Needless to say, 'mapping' between 'scan code' and ASCII is totally arbitrary (and up to the PC)

The keyboard actually contained 2 'processors', one based on an Intel 8041 micro-controller so the serial 'protocol' was based on the same 'bit banging' technique that we use with the PIC

Coding the PIC

Controlling the keyboard is actually harder than sending the ascii codes to the Pi. On the keyboard, you have to monitor the use of Caps Lock, Mum Lock etc. and set the appropraite LEDs as well as checking for simultaneous use of the Shift, Alt etc. keys. However, sending ascii codes to the Pi is just a matter of 'bit banging' the TxD line at 9600 baud. Since it's not possible' for the keyboard operator to press keys 'too fast', there is no need to check for any 'flow control' from the Pi.

Next subject :- PIC RTC