Parts: AT keyboard

atkeyboard

Last week we introduced a new version of the Bus Pirate universal serial interface tool. The last firmware update included an AT keyboard decoder library for both hardware versions.

There’s a ton of old AT keyboards making their way to the landfill. We’ll show you how to recycle one as an input device for your next project.

Connection

Bus Pirate PC AT keyboard (pin #)
SDA KBD Data (3)
SCL KBD Clock (1)
+5volts VDD (5)
GND GND (2)

AT keyboards communicate over a bidirectional two-wire interface. The bus is open collector, but keyboards already have internal pull-up resistors. The PC AT keyboard protocol is described here. We used our Bus Pirate tool to demonstrate the keyboard protocol, but the same basic principals apply to any microcontroller.

We connected the Bus Pirate to the keyboard as outlined in the table. We believe that this is a through-hole female AT keyboard jack, but we haven’t tested it. Do you know of a source for new sockets?

Protocol

The keyboard provides the clock signal for all data transfers; the PC side resembles a slave device. None of the existing Bus Pirate interface libraries work with an external clock, so we wrote a simple AT keyboard decoder library. The library depends on the keyboard’s clock signal, and it’ll hang if the keyboard fails or isn’t connected. If you use our library in your own project, consider adding a timeout delay in the readbit() and writebit() functions.

PC to keyboard command codes

Code Command
0xed Set status LEDs
0xee Echo 0xee
0xf0 Set scancode type
0xf3 Set repeat rate
0xf4 Keyboard enable
0xf5 Keyboard disable
0xfe Resend last byte
0xff Reset keyboard

A PC uses these commands to control various functions of an AT keyboard. The keyboard responds to commands with an acknowledge byte (oxfa). In our experience, the keyboard will reset if the response byte is not read shortly after the command is sent.

Keyboard to PC response codes

Code Response
0xfa Acknowledge
0xaa Self test passed
0xee Echo response
0xfe Resend last byte
0x00 or 0xff Error or buffer overflow

The keyboard has a number of single byte response codes.  Most PC commands are acknowledged with 0xfa. 0xaa is sent after a keyboard reset.

Setup the Bus Pirate

HiZ>m
1. HiZ

9. PC AT KEYBOARD
MODE>9 <–set mode
900 MODE SET
X02 PC AT KB DECODER READY
PC AT KEYBOARD>

First, we setup the the Bus Pirate for AT keyboard mode, option 9.

PC AT KEYBOARD>p <–power supply setup
W/w toggles 3.3volt supply?
1. NO
2. YES
MODE>1 <–no 3.3volt supply
W/w toggles 5volt supply?
1. NO
2. YES
MODE>2 <–use the 5volt supply
9xx SUPPLY CONFIGURED, USE W/w TO TOGGLE
9xx VOLTAGE MONITOR: 5V: 0.0 | 3.3V: 0.0 | VPULLUP: 0.0 |
PC AT KEYBOARD>W <–capital ‘W’, turn supply on
9xx 5VOLT SUPPLY ON
PC AT KEYBOARD>

Next, we configure the Bus Pirate’s power supply to provide 5volts for the AT keyboard.

PC AT KEYBOARD>r <–read byte from keyboard
x30 PCATKB READ:  NONE <–no data available
PC AT KEYBOARD>

The AT keyboard library follows the standard Bus Pirate syntax. Numeric values are sent to the keyboard as bytes, ‘r’ reads a byte from the keyboard. The protocol is clocked by the keyboard so bitwise operations are disabled.  If no data is available, the read will return ‘NONE’.

Setup the keyboard

PC AT KEYBOARD>0xee r <–send 0xee, read one byte
X20 PCATKB WRITE: 0xEE GOT ACK <–write oxee, got ack bit
x30 PCATKB READ: 0xEE <–read 0xee, echo was successful
PC AT KEYBOARD>

We can test the connection to the AT keyboard using the echo command, 0xee. The keyboard will respond 0xee if our connections are correct.

The keyboard responds to commands with an ACK bit at the protocol level, and then again with an ACK byte. We found that our test keyboards reset automatically if the ACK byte wasn’t read immediately after sending the command.

PC AT KEYBOARD>0xee <–echo command
X20 PCATKB WRITE: 0xEE GOT ACK <–wrote echo, got ACK
PC AT KEYBOARD>r <–read one byte
x30 PCATKB READ: 0xAA <–read 0xaa, reset indicator
PC AT KEYBOARD>

Here, we tried to send the echo command and then read the reply later. The keyboard reset automatically and replies 0xaa, self-test passed.

PC AT KEYBOARD>0xff r r <–reset command, read two bytes
X20 PCATKB WRITE: 0xFF GOT ACK <–write reset command, got ACK
x30 PCATKB READ: 0xFA <–command ACK byte
x30 PCATKB READ:  NONE <–read once more to reset
PC AT KEYBOARD>

The keyboard is reset by writing the command 0xff, and reading two bytes. The Keyboard won’t reset until the second byte is read.

PC AT KEYBOARD>r <–read a byte
x30 PCATKB READ: 0xAA <–reset success
PC AT KEYBOARD>

A short period after reset we can read the power on self test (POST) results, 0xaa indicates POST success.

PC AT KEYBOARD>0xf5 r <–disable the keyboard
X20 PCATKB WRITE: 0xF5 GOT ACK <–wrote command
x30 PCATKB READ: 0xFA <–read ACK byte
PC AT KEYBOARD>0xf4 r <–enable keyboard
X20 PCATKB WRITE: 0xF4 GOT ACK <–wrote command
x30 PCATKB READ: 0xFA <–read ACK byte
PC AT KEYBOARD>

0xf5 disables keyboard input. 0xf4 enables the keyboard and clears the buffer.

PC AT KEYBOARD>0xed r 0b111 r <–set indicator LEDs
X20 PCATKB WRITE: 0xED GOT ACK <–set LED command
x30 PCATKB READ: 0xFA <–command acknowledged
X20 PCATKB WRITE: 0x07 GOT ACK <–send LED value
x30 PCATKB READ: 0xFA <–value acknowledged
PC AT KEYBOARD>

The num, caps, and scroll lock LEDs are controlled by the 0xed command. The last three bits of a second byte (ob111) indicate which LEDs to light. It’s very important to perform all four byte operations within the keyboard timeout period, or the keyboard will reset.

PC AT KEYBOARD>0xee r <–echo test command
X20 PCATKB WRITE: 0xEE GOT ACK
x30 PCATKB READ: 0xEE
PC AT KEYBOARD>0xfe r <–repeat last byte command
X20 PCATKB WRITE: 0xFE GOT ACK <–write repeat command
x30 PCATKB READ: 0xEE <–previous byte is repeated
PC AT KEYBOARD>

The last interesting keyboard command is the repeat byte command. 0xfe causes the keyboard to send the last byte again. This is a useful command if there was a error in the previous transmission.

Read key presses

Key presses are buffered by the keyboard until we read them.

PC AT KEYBOARD>r <–read byte
x30 PCATKB READ: 0x29 <–space scancode
PC AT KEYBOARD>r <–read byte
x30 PCATKB READ: 0xF0 <–key release scancode
PC AT KEYBOARD>r <–read byte
x30 PCATKB READ: 0x29<–space scancode
PC AT KEYBOARD>

A key press sends scancodes, multi-byte sequences that represent the key presses. In the example, we pressed space which has the scancode 0x29. When a key is released, the keyboard sends 0xf0 and the scancode for the key (0x29). Each key press results in a similar three part sequence.

PC AT KEYBOARD>r:4 <–read 4 bytes
x31 PCATKB BULK READ, 0x04 BYTES:
0x29  0xF0  0x29   NONE <–space scancode
PC AT KEYBOARD>

This is just a simplified version of the previous example. Rather than read three bytes individually, we used the bulk read command. Again, we get the space scancode sequence. Our attempt to read a non-existant fourth byte fails.

Comments

  1. YenTheFirst says:

    I actually hooked up an old IBM model M to my arduino last week. how coincidental. :)

    As for sockets, what I did is take apart an old MIDI cable I didn’t need. MIDI uses the same physical connector (5-pin DIN), but it only uses three of the five pins, so you can’t just use those wires.
    I stripped it down to the actual connector, which had stubs for all 5 pins, and connected wires to the right ones.

    I can send/post pictures, if you like.

  2. marz says:

    I would be interested in seeing those photos :)

    I have an IBM Model M myself, best keyboard ever!

  3. DarkFader says:

    It was fun reading the bits into an 8 bit shiftregister on the Gameboy’s link port. Had to waste time in the interrupt to get the last 3 bits.
    But then I realized such keyboard was way too big for portable usage.

  4. deoryp says:

    I used a keyboard as input on my sr design project using an atmel based board (pre arduino). The really fun part about the keyboard is keeping the state of the caps/shift/numlock/scroll lock buttons and then talking back to the keyboard to turn those lights on and off…

    to interface I desoldered a ps2 connector from a scrap mobo and put it on a proto board… then i could use any ps2 keyboard, they all use the same base protocol.

  5. pragma says:

    “There’s a ton of old AT keyboards making their way to the landfill. ”

    You can have my Model-M when you pry it from my cold, dead hands.

  6. marz says:

    “You can have my Model-M when you pry it from my cold, dead hands.”

    QFT!!

  7. Benjamin says:

    To be honest…
    I still use mine as my preferred primary input device on my KVM switch with a PS/2 mouse that is at least 8 years old.

    I did try to upgrade but the quality’n’feel just isn’t near the same.

    I even added a connector for it in my hacked Commodore 64 DTV joystick.

  8. YenTheFirst says:

    First off, some pictures, as promised:
    my model M. It’s quite possibly older than I am.

    An old midi-computer cable I had.
    note: these pictures were taken after I had hacked it together. This cable used to have two MIDI female ends, as all MIDI cables do, one for in, one for out.
    top:

    front:

    first, I chopped off one of the midi ends pretty high up, but discovered that there were only three wires inside! after checking, I found out that MIDI only uses three of the pins.
    What I did then was chop off the cable at the base of the connector. Once that was done, the rubber jacket on the connector actually slid off quite easily, with a bit of force.
    Inside that, there was the metal connector, and a blob of some sort of plastic on the end. The plastic was a bit more difficult to remove, but once I got it off, I had a simple 5-pin din socket, with connector stubs on the other end.

    I wrapped and taped some wire on the end.
    results:

    top:

    front:

    and then that could be wired straight into an arduino, being at an electrically compatible level (I think).

    Does anyone have any advice on how to use an AT keyboard as a regular input device on a USB only computer?
    It looked like the PS/2 and AT protocols were pretty much the same, so could I wire in my keyboard to a ps/2 to usb adapter? What did other users do?

    Also, what does hackaday have against capital letters in the comments?

  9. Eric says:

    Here’s a cheap source of 6-pin Mini DIN sockets:

    http://www.goldmine-elec-products.com/prodinfo.asp?number=G13692

    5 for $1.00, 100 for $18.00, or 1000 for $155

    Regards,
    Eric

  10. YenTheFirst says:

    the problem with that, eric, and with what was linked in the article, is that those are MINI-DIN connections.

    That will work for PS/2, but AT keyboards use a regular sized DIN,with 5, not 6, pins

  11. Brett_cgb says:

    I’d like to suggest keeping the initial article to a paragraph or so, with links to the actual content. The very long page (as above) wreaks havoc with my RSS feed.

  12. bobby says:

    Try this site:

    http://www.allelectronics.com/make-a-store/item/DIN-5PC/5-PIN-DIN-JACK-PC-MT/-/1.html

    If memory serves, 5 pin microphone jacks use the same pin spacing…sorry, none on hand to confirm.

  13. jonjon says:

    plz………parts of keyboard

  14. Kyle says:

    I don’t suppose anyone has any experience using the bus pirate to hack a macbook keyboard? The cable coming from it has a 10 pin connector. Haven’t received the bus pirate yet, just wondering if someone can point me in the right direction first. Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 94,628 other followers