LK201 Interface
LK201 Keyboard Interface
Overview
Electrical Interface
Communications from the Keyboard to the Computer
Communications from the Computer to the Keyboard
- Overview
- LED Control
- Key Click Control
- Bell Control
- Key Control
- Autorepeat Control
- Power-Up and Self Test
References
DISCLAIMER
Overview
Introduction and Purpose
This page is intended to detail the DEC LK201 keyboard interface. If anything on this page is unclear or incorrect, please contact me and I will do my best to clarify and/or correct the document.
Electrical Interface
Electrical Specifications
This section describes the electrical interface between the LK201 Keyboard and the computer. Some of these specifications came from publication EK-366AA-OG-002 "DECstation 5000, Model 200 Hardware Operator's Guide, April 1990". The rest of the items in this section were experimentally determined (like the pin outs).
The LK201 is powered from a 12 Volt supply generated by the computer. The keyboard and the computer communicate via a fairly standard serial interface. The key specifications are listed here:
- Bidirectional asynchronous serial communication: 4800 baud, 8N1.
- Serial interface levels: EIA RS 423 (ie signals swing +/- 5 Volts).
- Power input: 4.2 Watts Max. 350 mA @ 11.8 Volts +/- 6%. (NOTE: This is the value quoted in the manual, but I measured 30 mA on a working LK201. Perhaps the 350 mA is the maximum the computer can supply?)
Connector Pinout
The pinout of the connector on the LK201 and on the computer in jpeg and postscript form are linked below.
|----- data -< -------------------------------------------| | |-------- >- Power -----------------------------| | | | |------------- GND -------------------| | | | | | |------------- <- data -----| | | | ------------------- ------------------- | " " " " | | " " " " | | L V G D | | D G V L | | K + N E | | E N + K | | -> D C | | C D -> | | D -> | | -> D | | E L | | L E | | C K | | K C | -- -- -- -- | | | | -- -- -- -- | | | | ------- ------- Looking into the Looking into the DECstation LK201 Connector Connector (Socket on keyboard) (Socket on DECstation)
Communications from the Keyboard to the Computer
Overview
The next two sections will refer to the following table and/or diagram:
(I had a hard time getting a jpeg version which was legible so please bear with me on the postscript format for now.)
Keyboard Modes
The LK201 keyboard has its keys divided into 14 distinct groups. These groups are indicated on the LK201 Keycode and Keyboard Division Chart/Table. Each of the groups is separately programmed for its behaviour with respect to keycode generation. There are three operating modes to select from.
-
LK_DOWN
mode: In this mode, the code indicated on the keycode chart is transmitted by the keyboard when the corresponding key is pressed. If held down, the key does not repeat and no further codes are generated. -
LK_AUTODOWN
mode: In this mode, the code indicated on the keycode chart is transmitted by the keyboard when the corresponding key is pressed. If held down the LK201 transmits theLK_REPEAT
value,0xB4
,repeatedly at the key repeat rate. It is up to the computer to know what key is being repeated. -
LK_UPDOWN
mode: In this mode, the code indicated on the keycode chart is transmitted by the keyboard when the corresponding key is pressed. In addition, a code is generated when the key is released. The release code is determined by the following rule. If no other keys inLK_UPDOWN
mode are pressed in addition to the one being released, theLK_ALLUP
,0xB3
is generated. If there is another key currently pressed which has been programmed forLK_UPDOWN
mode, the code indicated on the keycode chart is used for the key release code. If held, the key does not repeat.LK_UPDOWN
mode is used for keys such as SHIFT, and CONTROL. The computer recognizes that the SHIFT (or other "modifying" key) has been pressed and not released. In this manner, the computer knows to use the shifted character set. Once released, the computer sees the release code and switches back to the normal character set.
Communications from the Computer to the Keyboard
Overview
The LK201 accepts a handful of commands from the computer. These commands include programming the operational mode of each of the 14 groups of keys, control of the 4 LED's, control of the bell, and control of keyclicks.
Commands are send to the keyboard as either single byte commands or as a command byte followed by one data byte. Once again, the communication is 4800 baud serial.
LED Control
The 4 LED's on the LK201 are controlled by the computer.
Either the command LK_LED_ENABLE
or
LK_LED_DISABLE
is sent followed by 1 byte
which indicates which of the 4 LED's are affected. The
lower 4 bits of the data byte correspond to the 4 LED's.
For example, to turn on the caps lock LED, the following
two bytes would be sent:
LK_LED_ENABLE LED_LOCK
A sample code fragment which defines the LED control codes is shown here.
/* requires LED number data */ #define LK_LED_ENABLE 0x13 /* light LED */ #define LK_LED_DISABLE 0x11 /* turn off LED */ #define LED_WAIT 0x81 /* Wait LED */ #define LED_COMP 0x82 /* Compose LED */ #define LED_LOCK 0x84 /* Lock LED */ #define LED_HOLD 0x88 /* Hold Screen LED */ #define LED_ALL 0x8F /* All LED's */
Key Click Control
The LK201 accepts several commands relating to key clicks.
/* Requires volume data byte */ #define LK_CL_ENABLE 0x1B /* keyclick enable. Requires volume */ /* byte. This does not affect the */ /* SHIFT key. The CTRL key requires */ /* LK_CL_ENABLE and LK_CCL_ENABLE to */ /* have been sent before it clicks. */ /* All other keys are only controlled */ /* by LK_CL_ENABLE. */ #define LK_CCL_ENABLE 0xBB /* Enable keyclicks for the CTRL key. */ /* The CTRL keyclick volume is set to */ /* be the same as the rest of the keys */ /* LK_CCL_ENABLE sets a flag in the */ /* keyboard with is logically AND'ed */ /* with the LK_CL_ENABLE flag to enable*/ /* CTRL key keyclicks. */ #define LK_CL_DISABLE 0x99 /* keyclick disable */ #define LK_CCL_DISABLE 0xB9 /* CTRL key keyclick disable */ #define LK_SOUND_CLICK 0x9F /* causes the LK201 to sound a keyclick*/ /* max volume is 0, lowest is 0x7 */ #define LK_PARAM_VOLUME(v) (0x80|((v)&0x7))
For example, to enable keyclicks at full volume, the following data would be sent to the keyboard:
LK_CL_ENABLE LK_PARAM_VOLUME(0x00)
Bell Control
The keyboard bell control commands work in the same manner as the keyclick commands. The keyboard never generates a bell sound on its own. A bell sound is always at the command of the computer.
/* requires bell volume data */ #define LK_BELL_ENABLE 0x23 /* enable the keyboard bell. Requires */ /* volume data byte. */ #define LK_BELL_DISABLE 0xA1 /* disable the keyboard bell. */ #define LK_RING_BELL 0xA7 /* ring the keyboard bell */ /* max volume is 0, lowest is 0x7 */ #define LK_PARAM_VOLUME(v) (0x80|((v)&0x7))
Key Control
The LK201 provides 3 different operating modes for the keys. In addition, the keyboard is divided into 14 different groups which are shown in the LK201 Keycode and Keyboard Division Chart (postscript 136k) and also in the LK201 Keycode and Keyboard Division Table (html). The three operating modes are discussed in 2. Communications from the Keyboard to the Computer.
Programming of the keyboard mode is accomplished via 1 byte per group of keys
on the keyboard. The macro LK_CMD_MODE()
is used to form the
command. For example, to set division 2 (the numeric keypad) to LK_AUTODOWN mode,
we would transmit:
LK_CMD_MODE(LK_AUTODOWN,2)
Upon successful receipt of the command, the LK201 responds with
LK_MODECHG_ACK
. The macros and constants used for key mode
programming are listed below.
The details of the meaning of each bit in the mode command are listed below.
bit 7: PARAM bit. 1 = no parameter to follow 0 = parameter will follow bits 3-6: keyboard division bits 1-2: mode (00 = down, 01=autodown, 11=updown) bit 0: "type" don't know what that means, but should be set to 0.
In the examples below, the PARAM bit is set to 1 meaning that no parameter will follow.
#define LK_UPDOWN 0x86 #define LK_AUTODOWN 0x82 #define LK_DOWN 0x80 #define LK_CMD_MODE(m,div) ((m)|((div)<<3)) #define LK_MODECHG_ACK 0xBA /* sent by the keyboard to acknowledge a */ /* successful mode change. */ #define LK_PFX_KEYDOWN 0xB9 /* indicates that the next byte is a key- */ /* code for a key already down in a */ /* division that has been changed to */ /* LK_UPDOWN. I think this means that if */ /* for example, the 'a' key is in LK_DOWN */ /* mode and the key is being held down and*/ /* division 1 is switched to LK_UPDOWN */ /* mode, the keyboard will produce the */ /* byte LK_PFX_KEYDOWN followed by 0xC2 */ /* (KEY_A). */ #define LK_CMD_RPT_TO_DOWN 0xD9 /* This command causes all divisions which */ /* are programmed for LK_AUTODOWN mode to */ /* be switched to LK_DOWN mode. */ #define LK_CMD_ENB_RPT 0xE3 /* enables auto repeat on the keys */ /* which are in LK_AUTODOWN mode */ #define LK_CMD_DIS_RPT 0xE1 /* disables auto repeat on all keys, but */ /* does not change the mode that the */ /* divisions are programmed to. */ #define LK_CMD_TMP_NORPT 0xD1 /* temporary auto repeat disable. This */ /* command disables auto repeat for the key*/ /* which is currently pressed down. Auto */ /* repeat is re-enabled when another key is*/ /* pressed. */ #define LK_INPUT_ERROR 0xB6 /* sent by the keyboard if it receives an */ /* invalid command. */
The LK201 contains 4 autorepeat registers. Each autorepeat register controls how quickly keys repeat and if repeating is enabled. The 4 autorepeat registers are independent. Each keyboard division can be associated with 1 of the 4 registers. To associate a keyboard division with a particular autorepeat register, use the same command as setting the key division mode except set the PARAM bit to 0 and send a second byte which controls which autorepeat register is selected. The format of the second byte is:
bit7: 1 bits 2-6: 0 bits 0-1: number of the autorepeat register 00,01,10,11
For example, to set division 2 (the numeric keypad) to LK_AUTODOWN
mode, and associate it with autorepeat register number 2, we would
transmit: LK_CMD_MODE_AR(LK_AUTODOWN,2) 0x82
where the
macro LK_CMD_MODE_AR
is defined below.
#define LK_CMD_MODE_AR(m,div,arreg) (0x7F & ((m)|((div)<<3)) )
Autorepeat Control
The autorepeat rate is programmed by a 3 byte command.
first byte: bit7: 0 (means more bytes to come after this one) bits 3-6: 1 (means we're calling the rate change command) bits 1-2: number of autorepeat register (00,01,10,11) bit 0: "type" set to 0 second byte: bit7: 0 (more bytes to come after this one) bits0-6: time out value (how long to wait before beginning to autorepeat) this is in 5 ms increments. allowed range is 5 ms-630 ms. note: don't send 635ms, 0111 1111 is a reserved for internal use code. note: don't send 0ms, 0000 0000 is illegal. third byte: bit7: 1 (no more bytes after this one) bits0-6: autorepeat rate in number of generated key presses/second. lowest rate is 12 Hz. note: 125Hz (1111 1101) must not be sent (its identical to the powerup command)
Power-Up and Self Test
This section details the self test features and the power up sequence of the keyboard. Upon power-up, the keyboard performs a self test in 70 ms or less. The results are sent to the computer. The power-up self test results consist of 4 bytes.
Byte 1: Keyboard ID stored in the keyboard firmware. On my LK201, this is 0x01. Byte 2: Keyboard ID read from hardware jumpers. The documentation I have doesn't seem to quite match my keyboard (the docs say that the keyboard uses an 8051 microcontroller while mine uses a 68HC05C4). Anyway, the docs and my keyboard both say the result is 0x00. Byte 3: Error code. This byte indicates the result of the self test. Possible values are: 0x00 No Error #define LK_KDOWN_ERROR 0x3D /* Key down on powerup error */ #define LK_POWER_ERROR 0x3E /* Keyboard failure on pwrup tst */ Byte 4: Keycode. This byte contains the keycode of which key (if any) was pressed down on powerup. If no keys were pressed, this byte is 0x00.
If the keyboard passes all power up tests with no error, the resulting sequence sent to the computer is:
0x01 0x00 0x00 0x00
If the keyboard finds a key down on the first scan, it continues to look for an all up condition. When all keys are released, the keyboard transmits the correct 4 byte sequence (0x01 0x00 0x00 0x00).
Additional test commands are listed below.
#define LK_CMD_POWER_UP 0xFD /* This command initiates the keyboard */ /* power up sequence. */ #define LK_CMD_REQ_ID 0xAB /* This command requests the 2 byte */ /* keyboard ID. The keyboard responds */ /* with the same Byte1 and Byte2 as in */ /* the power up self test. */ #define LK_CMD_SET_DEFAULTS 0xD3 /* Restores the keyboard to its default */ /* state. This command sets the: */ /* division mode settings, */ /* auto-repeat interval and timeout rate, */ /* auto-repeat buffer selections, */ /* audio volume, */ /* ctrl key keyclick setting, */ /* to their power up defaults. */ #define LK_CMD_TEST_MODE 0xCB /* causes the keyboard to enter the */ /* factory test mode. This command */ /* should not be used. If received, the */ /* keyboard responds with LK_TESTMODE_ACK */ /* By sending a 0x80, the keyboard will */ /* leave factory test mode and jump to the*/ /* power up sequence. */ #define LK_TESTMODE_ACK 0xB8 /* sent by the keyboard in response to */ /* the LK_CMD_TEST_MODE command. */
The following are some additional keyboard control commands which didn't seem to fit anywhere else.
#define LK_CMD_INHIBIT 0xB9 /* This command suspends transmission */ /* the keyboard to the computer. The */ /* keyboard responds with LK_KBDLOCK_ACK */ /* and turns on the LOCK LED. */ #define LK_KDBLOCK_ACK 0xB7 /* send by the keyboard in response to */ /* the LK_CMD_INHIBIT command. */ #define LK_CMD_RESUME 0x8B /* Resumes normal keyboard operation after*/ /* the LK_CMD_INHIBIT command. */ #define LK_OUTPUT_ERROR 0xB5 /* If any keystrokes were lost while the */ /* keyboard was locked (LK_CMD_INHIBIT), */ /* then LK_OUTPUT_ERROR is generated by */ /* the keyboard when LK_CMD_RESUME is */ /* received. */
References
Sources of this Information
Much of this information came from NetBSD sources from mid-March,
1998. In particular, the files lk201.h
and
lk201.c
from src/sys/arch/pmax/dev/
is the
source of most of the code fragments on this page. Additional hints
came from the X11R5 Xserver code for OpenBSD (I think the OpenBSD and
NetBSD Xserver's are largely the same, at least with respect to the
keyboard stuff). I also got some good hints and a few
#define
's from an unknown version of Mach from Carnegie
Mellon. The files in the Mach source I looked at were also called
lk201.h
and lk201.c
, but were not the same as
the NetBSD files of the same names.
In addition to poking around the various pieces of code mentioned above, I hooked an LK201 up to the serial port on a NetBSD/mac68k machine and spent some time experimenting with the keyboard and the various control sequences. This is how I convinced myself of what the 14 keyboard divisions are. This test setup was invaluable for seeing exactly what the keyboard produces and how it reacts to known commands.
The text version of the keycodes and keyboard divisions was sent
to me by Dave. My brother,
Jeff, was also a big
help in answering many C
questions and pointing me towards
the Mach code.
In addition, I got a copy rather late in the writing of this page of what could be considered the "real" document for all this stuff. "VCB02 Video Subsystem Technical Manual" DEC Educational Services, AZ-GLGAB-MN, February 1986 The appendix of this document cleaned out most of the remaining mysteries.
DISCLAIMER
No Fault
Any software and documentation here is provided "as is", no warranty, use at your own risk. Please do not hook up your LK201 and/or computer backwards and blame me!