I’ve been typing on a dvorak layout keyboard for well over 5 years now and while OS based mechanisms for changing the keymap do work, the problem I keep running into is that things like the BIOS or UEFI don’t have mechanisms to change the layout from a qwerty based layout. Furthermore, some applications tend to grab keyboard scan codes directly in the background, bypassing the preferred layout (Dell, please fix your iDrac software so it works correctly).
Normally this wouldn’t be bothersome, but I’m not the average user. I do systems administration type things which usually take me into those BIOS screens and whatnot on a regular basis. My home keyboard is an IBM Model M and I got it *because* I could rearrange the keycaps so they would reflect the actual dvorak layout. At work, I use a DasKeyboard because it gives me the same tactile keyclicks, but there’s no labels on any of the keys. I find it very frustrating to suddenly be forced into a keyboard layout I don’t use and neither keyboard helps me in that situation. In those cases, I have to go find a regular keyboard to use temporarily until I’m done with the current task.
So, I wanted to learn verilog and I had a FPGA coming from kickstarter. I went out and purchased another DasKeyboard and then promptly took it apart. I think I did plug it in to make sure it worked, but that’s all I did. Inside the new keyboard there isn’t a lot of space to add other components, so there wouldn’t be any way to make this particular hack invisible, but when I’m done I would have a hardware keyboard that spits out the scan codes in dvorak sequence. Problem solved.
The way it would work is the host computer would think it has a qwerty keyboard attached, but all of the translation would be done in hardware. The FPGA would examine the lines that were scanning the keyboard matrix and then either store the state of each key temporarily or it would pass the signal right through back to the keyboard’s own microcontroller. What happens in the code really depends on what key gets pressed, but we’ll get to a discussion of that a bit later.
For those of you who don’t spend much time looking at USB specifications, the way a keyboard works is it sends sequences of scan codes to the host computer. The scan code isn’t the same as the key you’re pressing, it’s a number that corresponds to a keymap that’s been published as part of the USB HID specifications. The host computer sees the scan code and then uses that same map to figure out what key was pressed. Some applications, though, have this keymap hard coded to the qwerty keymap and that’s the problem.
So for this part of the write up, the main issue is that once the keyboard is apart, we then need to figure out what pairs of wires become connected when each key is pressed. In my case, there are 26 lines running from the keyboard microcontroller to the key matrix. I grabbed a multimeter and then carefully put together a listing of what column and row are connected as each key is pressed. The engineers that put DasKeyboard together were nice enough to silkscreen the name of each key on the circuit board, so it wasn’t as difficult as I thought it would be. From this, I learned that pins 11, 12, 16, 17, 18, 19, 21, and 22 are the rows. The remaining pins are the columns.
At this point in the process, we’ve taken apart the keyboard and gotten a map of where each key fits into the signals used to scan the key matrix. The next step was then to sit down with a dvorak layout and create something that shows what the signals would look like if it were a dvorak layout. For this, I started doing it with a spreadsheet, but that wasn’t flexible enough. I then went to using a MySql database to enter the qwerty key name, the pins used to locate that key, and the dvorak equivalent. For instance, the letter W in the qwerty layout is identified by signals on pins 7 and 19 of the connector but that key is a comma in the dvorak layout. To finish this row of data, we’ll also need to know what signals represent a comma in the dvorak layout. When done, you have something that looks like the following:
In essence, when I hit the W key, I want to activate the lines which correspond to the comma instead. The keyboard’s microcontroller will think I’ve hit a comma and it will send that scan code to the host computer. The FPGA will see lines 7 and 19 become active, but it will instead activate lines 1 and 21.
This is only part 1 of the project. There are several other posts coming which describe how I used the database to search for errors in my keymap and how I basically used the computer to generate the logic necessary to do this. I’m currently writing the verilog code on EDAplayground.com and should be able to code up a testbench soon. If you have a DasKeyboard and want the keymap data for your own project, let me know.