Things you'll need
- an Atmel AT90USB based controller board
- avr-gcc 4
- HumbleHacker firmware source code
- kspec code generator
Alternately, you can design and build your own AT90USB-based controller board. Any of AT901286/7 or AT90646/7 MCUs will work.
There are avr-gcc packages for the big three platforms. Installation instructions can be found on each site.
- Windows: WinAVR
- Mac OSX: AVR CrossPack
- Linux: depends on the distribution. For example, on Ubuntu execute:
sudo apt-get install gcc-avr avr-libc
HumbleHacker source code
Although there are tarballs and zipfiles available, it's best to just install and use git. That way you can easily update the source when bugs are fixed and features added. GitHub has good git installation instructions for each platform.
The source code can be found here. To get it, from the command-line, execute:
git clone git://github.com/humblehacker/keyboard.git
This will place the source code in a directory called
keyboard in your current directory.
kspec code generator
There are pre-built versions for each of the major platforms. Go to the downloads page on github and grab the latest version for your platform. Once you've downloaded it, extract the archive and place the resulting binary in the
firmware subdirectory of the
keyboard repository directory. For example, if you checked out the source code into:
then you would copy the kspec binary into:
Building the firmware
Now that everything is in place, you can build and install the firmware. Broadly speaking, we'll be performing the following steps:
- create your keyboard/controller specific project directory
- test build
- modify sources and makefile for your keyboard/controller
- test build and program
- modify layout files as desired
Instantiate project directory
keyboard/firmware. In this directory, you'll find a directory
kb_reference. This is your starting point for building a firmware specific to your keyboard/controller combo. You need to duplicate this directory, naming it whatever you desire. It's a good idea to keep the
kb_ prefix. In this example, I'll use
To ensure that your build environment is set up correctly, and all dependencies have been satisfied, it's a good idea to try to build the firmware prior to making any code modifications. From the command-line, navigate to
keyboard/firmware/kb_example and type
make. At this point you should have a successful build. If not, review the above instructions to make sure you haven't missed anything. If you're still having problems, contact me and we'll work them out.
There are a few things you'll need to change before you can program your controller with this firmware. All of the following files/paths are relative to the
You need to know two things before modifying the makefile: which microcontroller your controller will be using, and what its clock speed is.
With this information in hand, edit the makefile, and look for the line that reads:
MCU = at90usb1287 (roughly line 66). Change
at90usb1287 to whatever MCU is used on your controller board. If you're using an Atmel AT90USBKey, nothing needs to change. If you're using a Teensy++, change it to read
MCU = at90usb1286.
Next, look for the line that reads:
F_CPU = 8000000
If your clock speed is 8Mhz, nothing needs to change (USBKey). Otherwise, if your clock speed is 16Mhz, change it to read:
F_CPU = 16000000
config.kspec is where all the fun happens. In this file, you define your keyboard matrix, how that matrix is connected to your controller board, and all of the various keymaps you wish to define for your keyboard. The default file comes preloaded with useful maps, and with a bit of modification, you should be up and typing!
Fire up your favorite text editor, and open
config.kspec. Scroll down past the GPL commentary until you reach the line:
HumbleHackerReference to an identifier of your choice. For example, if you're modding a Kinesis Contoured keyboard, you would change it to something like:
Now let's go through the different sections, starting with the keyboard matrix.
Move down the file a couple of lines until you come to the line:
Here is where you define your keyboard matrix, and how that matrix is wired up to your controller board. Each key on your keyboard needs a unique identifier. A very simple method is to use numbers for rows and letters for columns. For example, on a standard QWERTY keyboard with the ESC key in the upper left, that key would have the identifier
1A (1st row, 1st col). Similarly, the Q key would have the identifier
3B (3rd row, 2nd col). If you already know your matrix, all you have to do fill in this table. For example, if the Q key (location
1A) is at row 0, column 12 of the keyboard matrix, you would modify the first line of the matrix definition as follows:
Matrix: /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */ /* 0 */ Row: -- -- -- -- -- -- -- -- -- -- -- 1A -- -- -- -- -- -- /* 1 */ Row: ...
But you're not limited to this scheme. If you prefer to just use the labels on the keys, you can do that too, with a few exceptions. Using the previous example, with the Q key at matrix row 0 column 12, your matrix definition would look like this:
Matrix: /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */ /* 0 */ Row: -- -- -- -- -- -- -- -- -- -- -- Q -- -- -- -- -- -- /* 1 */ Row: ...
The only problem with this is that your identifiers can't be special characters, (e.g.
|), so you'll have to come up with a good mnemonic.
If you don't know your matrix, see the section Matrix Discovery Mode, below.
After you define the matrix, you'll also have to define how the rows and columns of the matrix are connected to the controller board, or more specifically, which pins on the controlller's MCU are connected to which rows and columns of the matrix. Scroll down a few lines until your come to the
Let's say your keyboard has a matrix of 16 columns and 8 rows. Your
ColPins: entry would then be followed by 16 pin identifers and
RowPins: would be follewed by 8 pin identifiers. What's a pin identifier? Your MCU has various I/O ports (identified by letter), and each of these ports is divided into a set of pins (identified by number). For example, the Atmel AT90USB1286/7 (MCU on the Teensy++ and the USBKey) has 6 ports,
PORTF. On each of these ports there are 8 pins, labeled 0 - 7. So the first pin on
PORTC is labeled
PC0 is its pin identifier.
Once you've determined the pin identifier for each matrix row and column, just fill in the
RowPins entries. The following is an actual example from the Humble Hacker I keyboard:
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ ColPins:PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0 /* 0 1 2 3 4 5 6 */ RowPins:PA0 PA1 PA2 PA3 PA4 PA5 PA6
Now we need to define how the LEDs are connected to the controller board. An example LED definition looks like this:
LED:num_lock pin:PF0 flow:sink LED:caps_lock pin:PF1 flow:sink LED:scroll_lock pin:PF2 flow:sink LED:dv pin:PF3 flow:sink
You will have one
LED: definition for each LED connected to your MCU. Immediately following
LED: you must enter a name for the LED. This can be whatever you like, with a few exceptions. If you want your LED to act as a standard keyboard LED, you must use one of the five standard names:
Each LED must have one end connected to a pin on the MCU, and the other end connected to either Vcc or ground. You specify the pin by following the key
pin: with the pin identifier. If the other end of the diode is connected to ground, you would specify this by adding
flow:source to your LED definition. Otherwise, if it is connected to Vcc, you would add
flow:sink. ('source' means that the MCU is providing the voltage source to drive the LED, while 'sink' means that the MCU is providing the LED's ground).
Ghost key blocking
The final item in the matrix section is a simple on/off switch.
BlockGhostKeys: yes or no
For a good explanation of keyboard ghosting, see Dave Dribin's Keyboard Matrix Help page. Basically, if you are modding a membrane keyboard, you want to turn this on:
Otherwise, if your keyboard has mechanical keyswitches, most likely you want this off:
NOTE: the following process has changed and will soon be updated
Matrix Discovery Mode
This is a special firmware mode that can help you to determine the keyboard matrix for a keyboard that is not yet supported by the HumbleHacker firmware. Basically, you wire all the leads on your keyboards connector to pins on your controller board, then build and install the specially modified firmware. Once the firmware is loaded, the keyboard will interactively walk you through discovering the matrix.
Edit the makefile, and uncomment the line
MATRIX_MODE = 1
Edit the file 'matrix_discovery_defs.h' to specify which ports/pins are connected to your keyboard matrix. For example, if you connected one of the leads on your keyboard matrix to port D pin 3, you would find and uncomment the line:
Build the firmware, and program it into your controller board.
When the firmware resets, it will pause for a few seconds. During this time, switch to a text-editor such as TextEdit or Notepad. Make sure your keymap is set to US QWERTY. After the pause, the firmware will begin to write instructions to the editor.
Follow the instructions to discover your matrix!