Sun keyboard to USB converter
The SUN keyboard operates as a 1200bps RS232 device. It uses inverted, TTL-level signaling. On each key press it sends a code; when a key is released it sends its press code + 0x80. The keyboard also supports a number of commands, which include controlling its LEDs. Here's a detailed specification of the keyboard protocol, but I found that the scan code table isn't fully correct. See table.c in the source code for the correct table (the table index is the Sun scan code).
To talk to the keyboard the PIC's USART is used. When it receives data an interrupt is triggered, which then processes the received key code. By means of a table in EEPROM the Sun code is converted to an USB HID code. To build this table I used the OpenSolaris source code, which allowed me to map the virtual key codes reported by Type 5 keyboards to the ones reported by Type 6 keyboards, and as such the HID code sent by the Type 6 keyboard. This file details the different settings for special keys and their corresponding key codes. The alternatives to special keys have been chosen so that Windows gives them a virtual key code; there isn't much logic in which HID codes do and don't work. The general rule is that a key might work if it's in the keyboard HID class and it has a PS/2 equivalent.
The software works as follows:
- The USB module (full speed USB 2.0), USART, and keyboard are initialized.
- The microcontroller goes into an infinite loop exchanging USB data and updating the keyboard's LEDs if needed.
- An interrupt triggers when data is received from the keyboard.
- In the interrupt code the following happens:
- The keyboard's initialization sequence is handled, reporting a HID error to the PC if it fails.
- If USB is in suspend mode, receiving a press of the keyboard's power key will reset the microcontroller, a (hacky) way to wake the PC up.
- The scan code is run through the settings handler. If the scan code is scroll lock, settings mode is initiated until it is released. If in settings mode, keys are remapped to their alternative functions by rewriting the EEPROM Sun->HID table.
- Next, if the key code is a press code (<0x79), the key's HID code is added into the list of pressed keys (which is exchanged with the computer in the aforementioned loop). If too many keys are pressed a HID error code is reported. If the scan code is a release code, the key is removed from the list or, if the allowed amount of pressed keys is reached, the HID error is retracted. Note that all pressed/released keys are processed to see if they're modifier keys (ctrl, shift, etc). These keys aren't put into the pressed key list, but are converted to a series of flags stored in a separate part of the HID data packet as per the HID boot protocol. This is done after they're converted to HID codes, so modifier keys can be remapped (meta becomes alt, etc).
Click here to download the source code. It's written in C for Microchip's C18 compiler, which integrates with their MPLAB IDE.
To debug the software I recommend connecting the chip to a PC by means of Microchip's software UART library, which allows the pins of the microcontroller to emulate a second serial port. The converter code already uses this library to show the codes of keys pressed on the Sun keyboard. To enable this, define _DEBUG in the project settings. A MAX232 chip is required. For more information see the C18 documentation.
The code compiled for use with Microchip's USB bootloader. To do so, use the rm18f4550.lkr linker script and define BOOTLOADER in the project settings.
Switching to an 18F2550 chip is be effortless, software wise. The 2550/4550 linker scripts are identical.
A final note: the converter isn't 100% USB compliant as it violates the USB 2.0 spec (section 7.2.3) in two ways: the device consumes more thanone unit load (100mA) even before it has been configured, and while the device is in suspend state it consumes more than 2.5mA. These are due to the fact that the converter powers the keyboard (~150mA) over USB, and always keeps it powered. If this is a concern, the keyboard can be powered by means of a relay connected to one of the chip's pins and powered down (and perhaps the chip put in sleep mode) when USB is suspended. I personally haven't had any problems with the way the converter currently works though. It requests 200mA in its descriptor.