-
Notifications
You must be signed in to change notification settings - Fork 6
Make a good PS/2 keyboard to USB adapter from an ATmega32u4 [Adafruit breakout board]
License
nsd20463/ps2_kbd_to_usb_adapter
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This file is part of ps2_kbd_to_usb_adapter, copyright (c) 2014 Nicolas S. Dade ps2_kbd_to_usb_adapter, is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ps2_kbd_to_usb_adapter, is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ps2_kbd_to_usb_adapter. If not, see http://www.gnu.org/licenses/ ----------------------------------------------------------------------------- WHAT This code uses an ATmega32u4 as a PS/2 keyboard to USB keyboard converter, to allow using a good ole IBM Model M (or Northgate Omnikey Ultra) AT or PS/2 keyboard with modern computers which now (2014) lack any PS/2 ports at all. ----------------------------------------------------------------------------- BUILD To use this, install the AVR toolchain ('apt-get install gcc-avr avrdude avr-libc'), fetch the LUFA library (http://www.fourwalledcubicle.com/LUFA.php) (version 140302 is the one I am using), edit the LUFA_PATH in Makefile to point to where the LUFA library source as been unpacked, and type 'make'. If you are using the Adafruit ATmega32u4 breakout board then 'make flash' while the bootloader is running (red light is pulsing) will program it. Otherwise use whatever mechanism you usually use and the 'adapter.hex' (or .bin) file. You should enjoy customizing the USB descriptor as described below. ----------------------------------------------------------------------------- WHY I wrote this after trying two commercial adapters and finding neither worked very well. Keys would remain stuck down (or rather, the UP keystroke from PS/2 didn't register). In this code PS/2 receive is done in hardware using the ATmega's UART set in a mode which matches what PS/2 uses (externally clocked, odd-parity, 1 stop-bit). In addition the code asks the keyboard for resends (0xFE command) when a parity error occurs. The combination of these two features is what makes this code more reliable than the commercial adapters and other low level PS/2 libraries I've tried. I like the low latency of PS/2 (~1 msec for DOWN, ~2 msec for UP). The typical polling rate of USB keyboards is 10 msec. This was the rate suggested by the keyboard example in the USB 1.1 HID spec back in 1997 and nearly everyone copied it verbatim. The exception is the so-called "gaming" keyboards. A polling interval of 10 msec means your keystroke waits inside the keyboard for up to 10 msec before the computer polls the keyboard and learns the key has moved. I can't do anything about the extra latency caused by sending keystrokes first over PS/2 and then over USB, but I can minimize the USB latency by upping the polling interval to 2 msec. This faster polling is of no consequence on modern PCs and USB busses, which all run may times faster than anything from 1997 could. The fast polling also helps if you enjoy configuring the keyboard to have rapid repeat rates and short repeat delays, a configuration combination where prompt and accurate UP events are necessary. Myself I use 88 chars/sec after a 175 msec delay because I'm not so young anymore. I like using the Adafruit ATmega32u4 breakout board (https://www.adafruit.com/products/296) because its bootloader (accessed by pressing the reset button) allows for quick and easy reflashing over USB, without requiring connecting to the 6-pin ICSP header. But any board with an ATMega32u4 will do, for example the Teensy 2.0 or even an Arduino Leonardo should do (you're on your own, though). Just be sure the XCLK1 signal is easily available. Some ATmega32u4 boards don't bring it out to a header. For example the SparkFun Pro Micro board uses the XCLK1 pin (which is also PD5) to drive an LED. You can tap into it anyway, but it's more delicate work than would otherwise be necessary. The make target 'flash' (as in "make flash") and the configured target in the makefile are setup for the Adafruit ATmega32u4 breakout board. Edit as needed. ---------------------------------------------------------------------------- CUSTOMIZING and TROUBLESHOOTING In order to use this code you should customize a few things. Specifically in the USB descriptor you should set your own strings for the manufacturer, device and serial number of your keyboard. I like to set these to the exact keyboard I am building the adaptor into, just for fun. The constants are named usb_manufacturer_str, usb_product_str and usb_serial_str. The keyboard and descriptor describe an US English keyboard. With help from kreijack non-US keyboards should be supported. However all I know is English and Italian keyboards work. That is because I don't have anything else to test with. If you want to use this with a different language you should edit the CountryCode field in the descriptor (google for the USB 1.1 HID spec for the value you need, or use 0 like most keyboards do), AND you must edit the mapping from PS/2 scan-code set 3 keycodes to USB keycodes in keycodes.c. The latter step will be tedious. Tough. It was for me as well. :-) Scan code information can be found at http://www.quadibloc.com/comp/scan.htm If you have measured it you can set the correct power requirement in the descriptor in the MaxPowerConsumption field. Do note that PS/2 ports supplied ample power (5V/275mA) and the older the keyboard the more of that it used. So if you are plugging the adapter into an unpowered USB hub you might get an error (see dmesg on linux) that the device requires too much power to operate. In that case you can use a combination of two things: use a USB port on the PC itself or on a powered hub (the right thing to do), or in a pinch, hack the value of MaxPowerConsumption to something the PC will accept. However if you do the latter and don't supply the needed power the keyboard can become erratic, or the USB port can notice the extra power draw and shut off, or any sort of undocumented behavior. So never-mind my mentioning it :-) -- Nicolas S. Dade <you can find my email by googling my name>
About
Make a good PS/2 keyboard to USB adapter from an ATmega32u4 [Adafruit breakout board]
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published