beakl wi'd

friday, 29 january 2021

the main BEAKL development test bed platform for the past two years has been the Chimera Ergo 42 and Corne 42 key keyboards. They both share the same codebase including all the layers with only a single configuration file directive required to distinguish the keyboards for ROM flashing.

The Planck and Splitography keyboards on the other hand have required separate updates of their codebase to incorporate the evolving functionality of BEAKL Wi—the Splitography more so than the Planck because it is designed primarily for use as a steno keyboard.

With the recent addition of togglable hexadecimal case, number pad brackets, pinkie finger stagger and smart delimiters, and refactoring of the BEAKL Wi codebase, an effort was made to more fully establish a common codebase across all these keyboards for ease of maintainability—the only difference being the specification of the keyboard layers unique to each keyboard.


the Planck’s extra 6 bottom row keys are the distinguishable feature (from a software perspective), hence, it was integrated in a straightforward manner without difficulty. These extra keys are designated as one shot modifiers—for lack of any real use for the keys! The toggle layer keys are moved to the innermost columns to maximize the hand spread ergonomics..

Planck BEAKL Wi

Other than the seldom used one shot modifiers, everything else performs identically to the split keyboards, albeit with a more cramped feel.


the finger cluster for the Splitography, like the others, is the same but the 4 steno thumb keys require the addition of dual key press and dual thumb combinations to raise all the possible layers..

Splitography BEAKL Wi

layer left left left thumb right thumb right right
number X      
regex   X    
symbol     X  
cursor       X
fn X X    
mouse   X X  
capslock     X X

Similar to the Planck, the layer toggle keys are placed on the inside so the finger clusters rest on the outer columns. This provides the most comfortable thumb placement position. The light Matais keyswitches plus the flat steno keycaps make pressing both thumb keys simultaneously—a common steno action—easy to accomplish without effort.

For those unfamiliar with my Splitography development, Enter is facilitated with Shift Space—a surprisingly efficient chord. Because of that, the Splitography loses the paragraph or new line leader capitalization but retains all the other punctuation and Space leader capitalization shortcuts.

One change made different from previous Splitography BEAKL iterations is the duplication of the cursor keys on the Symbol Layer..

Splitography Symbol / Cursor Layer

This provides for quicker access as well as improved comfort. The original Cursor / Edit Layer remains and provides additional modifier chords in combination with the cursor keys (for Vim editing).

under the hood

the new consolidated codebase has been changed substantially from previous BEAKL layouts—even from the prior BEAKL Wi iterations (so code followers beware)!

The function library has actually been reduced with many keycode “primitives” replaced by inline macros. This has not been done to save CPU cycles—as the fastest typing possible does not come close to taxing the processor—but is a somewhat arbitrary decision to trade up some stack processing for an equivalent few extra bytes of space.

In other instances, statement macros have been defined to provide increased code readability whilst hiding unnecessary details. At least, that is the intent!

Macros have been used extensively in the keymap.c mainline to increase code density whilst reducing the code noise (of previously expanded statements) of common blocks of keycode processing. The hexadecimal keypad is a good example..

static bool hexcase = HEXADECIMAL_CASE; #define HEX(m, k, c) mod_roll(record, m, hexcase, k, c); break bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { ... case HEX_A: HEX(0, KC_A, 1); case HEX_B: HEX(MOD_LALT | MOD_LCTL, KC_B, 2); //** case HEX_C: HEX(0, KC_C, 3); case HEX_D: HEX(KC_LCTL, KC_D, 1); case HEX_E: HEX(KC_LALT, KC_E, 2); case HEX_F: HEX(KC_LSFT, KC_F, 3); ...

**An example of deeper changes, functions previously accepting multiple modifier parameters to define modifier chords now accept a single modifier keycode or a modifier chord bitcode. This was inspired by earlier coding efforts to utilize a single modifier bitcode in place of multiple modifier keycodes but this ended up costing more CPU cycles (with additional code) to manage the active “mods” state—which this approach avoids with a simple localized modifier test..

static uint8_t mods = 0; #define MOD_BITS(k) if (KEY_DOWN) { mods |= MOD_BIT(k); } else { mods &= ~(MOD_BIT(k)); } #define MOD(k) register_code (k); MOD_BITS(k) #define UNMOD(k) unregister_code(k); MOD_BITS(k) // smart chording (0) none (KC_*) modifier keycode (MOD_* | ..) compound modifier bitcode #define CHORD(k) if (k) { if (IS_MOD(k)) { MOD(k); } else { register_mods((uint8_t) k); } } #define UNCHORD(k) if (k) { if (IS_MOD(k)) { UNMOD(k); } else { unregister_mods((uint8_t) k); } }

»»  hex keypad revisited

comment ?