DasDvorak, part 2


Above is a graphic from wikipedia.org showing the keyboard layout we’re trying to create.  Note that only the central portion of the keyboard is different.  About half of the keys will remain right where they are.

In this post, we’re going to take a look at how I went about detecting errors in my keymap data.  Any problems we can eliminate early on will be problems we don’t have to deal with later and the database makes this rather easy to do.

We’ll start with identifying our rows and columns again.  We know that pins 11, 12, 16, 17, 18, 19, 21, and 22 are the rows for our key matrix.  Get very familiar with this set of numbers – we will use them a lot as the project progresses.  The first task is to query our table and make sure that both the qwRow and dvRow columns only contain these numbers.  If either column contains anything else, it’s a transcription error that crept into the data somewhere along the way and it needs to be fixed.  Here are a couple of queries that help do that:

select distinct qwRow from keymap;
select distinct dvRow from keymap;

Once those errors are corrected, then the same can be done for the column rows:

select distinct qwCol from keymap;
select distinct dvCol from keymap;

Again, the only thing that should show in the results pane are the columns: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 20, 23, 24, 25, and 26.

The final step is a bit more interesting.  Both the qwerty and the dvorak row/column pairs should correlate with each other.  It’s a bit hard to explain how that is, but in the end, we’re checking for consistency between the two views of the table.  These views help in ensuring that the keymap data is consistent.  Here’s the query:

select a.qwKey, b.dvKey
from keymap a, keymap b
where a.qwCol = b.qwCol and
a.qwRow = b.qwRow and
a.dvCol = b.dvCol and
a.dvRow = b.dvRow
order by qwKey;

The trick I’ve used above is an old one that has come in handy many times.  I purposely joined the same table to itself and forced the arrangement of the data so that each keyname from both layouts would be displayed together.  Once this is done, it’s fairly simple to visually scan through the results for problems.    Here is a snippet of the results:


If you take a look at a qwerty keyboard and then compare it to the graphic at the top of this post, you can see that where there is a G in a qwerty layout, there would be an I in the dvorak layout.  The Home and Insert keys would remain in their same position in both layouts.

Finally, lets try another query:

select a.qwKey, b.dvKey
from keymap a, keymap b
where a.qwCol = b.dvCol and
a.qwRow = b.dvRow
order by qwKey;

This one will yield a somewhat surprising result.  It will show you two columns of keynames and they should all be the same across each row:


This query puts the key translation into the where clause of the query, which makes the result set show if there are any inconsistencies.  At the end of the day, each key can only be represented once for each layout.  The forwards and backwards examination of that translation should be consistent.  If any problems do show up, you have an opportunity to debug it now before we’re about 500 lines deep in verilog code.

Next time, we’ll take a look at how we’re going to implement the key translation.  That post will be mostly about the theory behind the design.  Do note that if you’re not comfortable with sql queries, it might seem to get a little bit more complicated from here, but we’ll really only be using the same multiple-joins trick in a slightly different way.

DasDvorak, part 1

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.