Specifications

Firmware Implementation
The reference firmware supports both the USB and PS/2 interfaces. For each interface, the firmware can be conceptually
divided into the following sections: host command processing, scan code conversion, and keyboard matrix scanning. Of
these tasks, the keyboard matrix scanning is common to both interfaces and, as such, is organized as a set of callable
functions which scan the keyboard and return interface-independent information about the state of the keys. The information
regarding the key states must be uniquely converted to the proper format for each interface (scan code conversion) prior to
transmission to the host. In addition, both interfaces require support for interface-specific host commands that configure
the keyboard; for USB, this includes enumeration and setup, and for PS/2, this includes such commands as selecting the
scan set, selecting the key repeat rate and delay (typematic functionality), and enabling/disabling scanning.
Code Organization
The supplied reference firmware supports four variants: a usb keyboard, a ps2 keyboard, a usb/ps2 dual-interface keyboard,
and a usb with slave mouse/ps2 dual-interface keyboard (refer to the readme.txt in the reference firmware distribution for
detailed instructions on building each variant). Code for the usb-only and ps2-only implementations is less than 4k in size.
However, the code size for both dual-interface implementations is larger than 4K; this places a constraint on the
organization of the firmware due to the microcontrollers restriction that code residing in the upper 4K of memory cannot call
routines residing in the lower 4K (the reverse, however, is possible). To effectively circumvent this limitation, the main
control loop and host command processing modules for both USB and PS/2 reside in the lower 4K of ROM, while the
subroutines that these modules invoke (keyboard scanning, scan code conversion) are placed in the upper 4K.
In addition, ISRs for both interfaces reside in the lower 4K in accordance with the hardware interrupt support provided by
the microcontroller.
Since the dual-interface firmware detects the type of interface (USB or PS/2) dynamically upon power-up (which commences
when the keyboard is plugged into the computer, or the computer itself is turned on), the USB-specific firmware and PS/2
specific firmware never run simultaneously. Thus, static variable assignment and other RAM usage for the two separate
host interface firmware modules can overlap, reducing overall RAM requirements. Since the keyboard martrix scanning
routines are utilized in both USB and PS/2 situations, the RAM associated with this task cannot be shared with other
functions and is statically allocated in its own area of RAM.
In normal operation, the control flow is roughly the same for both USB and PS/2 interfaces, although their modules remain
entirely distinct. After power-up housekeeping is performed and the keyboard scanning is enabled, the firmware enters a
loop, from which it periodically invokes the keyboard matrix scanning subroutine. The key-scan module converts
row/column key information to generic key numbers, which are in turn converted by scan-code conversion modules to the
required scan codes for the currently active host interface. A separate scan-code conversion module exists for each scan-set
required, and the key-scan module invokes the scan-code conversion module corresponding to the currently-selected host
scan set (e.g., USB, PS/2 Scan Set 1, PS/2 Scan Set 2 or PS/2 Scan Set 3). USB supports only one scan set, while PS/2
supports three separate host-selectable scan sets. When the keyboard matrix scanning subroutine returns, the converted
key press information just collected by the scan conversion code can be transmitted to the host from the main loop.
Auto-Interface Mode
The dual-interface keyboard determines upon power-up whether it is attached to a USB or PS/2 interface. This is
accomplished as follows.
Upon detecting power, the microcontroller implements a 128mS delay, after which code execution begins at the Reset
vector. The firmware sets the D+/D- lines to Hi-Z, leaves the USB pullup resistor disconnected from the D- lines, then
institutes an additional delay of 10mS. With the D+/D- lines in Hi-Z, the 15K-ohm pulldown resistors on a USB host will
cause both lines to be pulled to 0V (disconnected). If the interface is PS/2, the idle-state pullup resistors on the PS/2 host will
cause both lines to be pulled to Vcc.
The host determination is complicated somewhat by the fact that a PS/2 host will often times place the port in an inhibit state
by holding the PS/2 clock line low. Unless the host is attempting to transmit data, however, the data line will still be pulled