Ishpeck's Adventures in KLL Hell

Table of Contents

A couple years ago, I began my journey into the mechanical keyboard world. After trying various layouts and configurations, I found that the Poker II was painfully close to my ideal keyboard but there were some things about it that annoyed me a lot.

So when I found the Infinity keyboard kit on Massdrop last year, I had to have it. A fully programmable 60% keyboard was like a dream come true. I placed the order and while I waited, I watched a ton of youtube videos on how to solder.

When the kit finally arrived I was a bit nervous because this would be the first soldering job I'd done. Turned out that part was really easy and the thing that would be actually painful was the thing that I was worried the least about: configuring the layout.

1 Web Confugurator is Broken!!!!1!!1!!oneBANG

When I first got my board, I used the web configurator to create my layout. It's horrendously broken. It's garbage. If you made the mistake of trying to use it, you'll notice the yellow LED on your keyboard won't ever turn off like it should. I fixed this by flashing this default firmware onto the keyboard:

https://s3.amazonaws.com/configurator-assets/kiibohd.dfu.bin

Instructions on how to do that are found in the build guide linked below.

2 KLL is hell

The Keyboard Layout Language has all the properties of terribly incoherent design by committee. The spec probably great for the kids who frequent the Deskthaurity forums and helped build the damn thing but for me, a full-time programmer of 15 years who has worked in systems development, it's pretty opaque. Maybe I'm just illiterate.

I'm now of the opinion that it would be easier to just write my own firmware in C than it would be to master the KLL.

But in the mean time, here's some minutes from my fumbling around until I got the keyboard layout that I wanted.

3 Dependency hell is hell

The first thing I did to get this working was install macports. I'd had it installed before but mostly ignored it. I hadn't noticed that after upgrading to Yosemite that a bunch of my ports were borken. I had to go back and reinstall all that.

https://guide.macports.org/#introduction

Once that's installed, I needed to install the dfu-util and friends as advised in this:

https://www.massdrop.com/keyboard/infinity/assembly

I also had to install a bunch of other inane dependencies that weren't clearly called out as dependencies in any of the things I read.

sudo port install cmake git ctags python3 make

Again, maybe it's just because I'm illiterate.

4 The Controller Source

Once those are all installed, I was should be able to clone the source repository for the controller…

mkdir -p ~/proj/kiibohd
cd ~/proj/kiibohd
git clone https://github.com/kiibohd/controller.git
cd controller
mkdir build
cmake ..
make
    

I my eyes glazed over as the colorful make output flew past my screen and the process pooped out a kiibohd.dfu.bin file with the default key map. I was able to flash that onto my board and it worked without any issues.

I tried cloning the KLL repository from github as well but soon found that it was completely worthless. I didn't even need it because KLL is bundled in the controller repo anyway.

5 KLL is something of a misnomer

Even though KLL is billed as a kind of programming language, it really doesn't behave like one. The implementation included with this controller seems to depend so much on C that it's more accurately described as a messy lookup table binding some scan codes to C functions. This isn't really apparent in the documentation or any other description of KLL. The hardest part in learning to work this stuff was getting the misconception that KLL was a language out of my head entirely.

The kll.py script requires you to feed it a bunch of .kll files that it will use to generate header files that, when you compile with make, should yield working firmware with the desired keyboard layout. But the content of the KLL files alone is not enough to get you there. You also know how to work the python script's undocumented command line arguments.

The most helpful/inforamtive file was the header file generated by the build process; kll_defs.h

This file was what I needed to create the basic scaffolding and start editing the base layer to my liking…

6 The Basic Layer

kll_defs.h has a comment section called "compiler arguments" that shows the kll call with all the appropriate files (with absolute paths) and all the command line switches needed to get those files to work correctly.

I ended up copying out that entire comment section and turning it into a command that I pasted into the terminal. After running that, I was able to run make and get a working .bin file again. The final command looked like this:

../kll/kll.py /Users/ishpeck/proj/kiibohd/controller2/Scan/MatrixARM/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Macro/PartialMap/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Output/pjrcUSB/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Scan/MD1/defaultMap.kll -d /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/md1Overlay.kll /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/stdFuncMap.kll -p /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/hhkbpro2.kll –backend kiibohd –templates /Users/ishpeck/proj/kiibohd/controller2/kll/templates/kiibohdKeymap.h /Users/ishpeck/proj/kiibohd/controller2/kll/templates/kiibohdDefs.h –outputs generatedKeymap.h kll_defs.h
    

I put that into a shell script called "genlayout.sh"

#!/bin/sh
../kll/kll.py /Users/ishpeck/proj/kiibohd/controller2/Scan/MatrixARM/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Macro/PartialMap/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Output/pjrcUSB/capabilities.kll /Users/ishpeck/proj/kiibohd/controller2/Scan/MD1/defaultMap.kll -d /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/md1Overlay.kll /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/stdFuncMap.kll -p /Users/ishpeck/proj/kiibohd/controller2/kll/layouts/hhkbpro2.kll –backend kiibohd –templates /Users/ishpeck/proj/kiibohd/controller2/kll/templates/kiibohdKeymap.h /Users/ishpeck/proj/kiibohd/controller2/kll/templates/kiibohdDefs.h –outputs generatedKeymap.h kll_defs.h
make
    

And made it executable:

chmod +x genlayout.sh
    

Ran ./genlayout.sh and it generated a new .bin file which I was able to install to the keyboard with ./load after pushing the flash firmware button under the keyboard (as instructed in the build guide web page).

Then I made my own default map file like so:

cp ../Scan/MD1/defaultMap.kll ../Scan/MD1/myDefaultMap.kll
    

I edited ../Scan/MD1/myDefaultMap.kll so pipe/backslash was in the key just above enter and so the last two keys on the top row were backspace and delete.

The lines that achieved this were…

S0x0D : U"Backspace";
S0x0E : U"Delete";
    

… and…

S0x1C : U"Backslash";
    

With that edit in place, I re-ran genlayout.sh, pushed the button on the keyboard and ran ./load and it worked! Huzzah! Now I can make a hardware dvorak layout!

7 Cloning my Vortex Poker II layout

Because I missed the function layer of my Vortex Poker II, I decided to emulate it …

cp ../kll/layouts/hhkbpro2.kll ../kll/layouts/pokerish.kll
cat genlayout.sh | sed -e 's/hhkbpro2.kll/pokerish.kll/' > genlayout2.sh
    

My pokerish.kll file looks like so:

Name = pokerish;
Version = 0.1;
Author = "Ishpeck 2015";
KLL = 0.3;

Date = 2015-03-02;

U"1" : U"F1";
U"2" : U"F2";
U"3" : U"F3";
U"4" : U"F4";
U"5" : U"F5";
U"6" : U"F6";
U"7" : U"F7";
U"8" : U"F8";
U"9" : U"F9";
U"0" : U"F10";
U"{" : U"F11";
U"}" : U"F12";
U"Backtick" : U"Esc";

U"Comma" : U"Up";
U"C" : U"Insert";
U"L" : U"PrintScreen";
U"Slash" : U"ScrollLock";
U"Equal" : U"Pause";

U"A" : U"Left";
U"O" : U"Down";
U"E" : U"Right";
U"S" : U"Home";
U"Minus" : U"PageUp";

U"B" : U"VolumeDown";
U"M" : U"VolumeUp";
U"W" : U"Mute";
U"V" : U"End";
U"Z" : U"PageDown";

8 An original layer

After I'd done all that, I had to learn (through trial and error) that if I wanted to have another layer, I had to fuss around with the kll.py call and pass in switches/files in the right order. I created a new shell script to make it easy for me. It looks something like this:

#!/bin/sh
../kll/kll.py /Users/ishpeck/proj/kiibohd/controller/Scan/MatrixARM/capabilities.kll /Users/ishpeck/proj/kiibohd/controller/Macro/PartialMap/capabilities.kll /Users/ishpeck/proj/kiibohd/controller/Output/pjrcUSB/capabilities.kll /Users/ishpeck/proj/kiibohd/controller/Scan/MD1/dvorakMap.kll -d /Users/ishpeck/proj/kiibohd/controller/kll/layouts/stdFuncMap.kll -p /Users/ishpeck/proj/kiibohd/controller/kll/layouts/pokerish.kll -p /Users/ishpeck/proj/kiibohd/controller/kll/layouts/coder.kll –backend kiibohd –templates /Users/ishpeck/proj/kiibohd/controller/kll/templates/kiibohdKeymap.h /Users/ishpeck/proj/kiibohd/controller/kll/templates/kiibohdDefs.h –outputs generatedKeymap.h kll_defs.h
make
    

I created a new layout file called "coder.kll" which scratched some personal itches.

The real take-aways here are …

  1. md1Overlay.kll was hideous and unwanted (I hate stateful keyboard)
  2. An extra "-p" was necessary to get coder.kll to appear as the layer 2 layout
  3. KLL sucks

Here's the final product:

http://www.keyboard-layout-editor.com/#/layouts/a3e4c0fc96f269e8871d034fd0665e2e

http://www.ishpeck.net/ishy-2015-03Mar-10.dfu.bin

Author: Anthony Tedjamulia

Created: 2015-03-10 Tue 12:39

Emacs 24.4.1 (Org mode 8.2.10)

Validate