m4_include(head.html)

Framework is Awesome

m4_include(nav.html)

UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.

Doug Gywn

Framework and the EC

Framework — for those unaware — is the coolest laptop manufacturer ever. Their whole shtick is producing laptops that give the user the ability to easily and effortlessly disassemble, repair, and modify their hardware. I highly suggest checking them out if you’re interested in computer hardware at all. The laptops even have hotswappable I/O!

Anyways getting back on topic, Framework has also been giving power to the user on the software-side of things too! A good while ago they open-sourced the code for the embedded controller of their laptops, which offers all sorts of possibilities for customization of the keyboard, LED lights, and more.

LED Fun!

This is an area of the EC which I have not really looked at or touched much. I do want to play around with this a lot more in the coming future though! So far just for shits-and-giggles, I’ve patched the EC to make the power-button LED green instead of the normal boring white:

~/board/hx20/led.c
m4_fmt_code(led.diff.html)

As you can see, it’s all fairly simple. I just had to change our EC_LED_COLOR_WHITE for EC_LED_COLOR_GREEN. The codebase defines a few colors, but they’re defined as RGB tuples which is awesome, because it opens the door to custom RGB effects in the future!

There’s More Than One LED!?

That’s right! The Framework laptop I own (13″; the 16″ releases soon though!) has 3 more LED lights. One on the left of the chassis, one on right of the chassis, and one on the capslock key. The capslock LED acts as an indicator of whether or not you’ve got capslock enabled. This is useless to me though, because my custom keyboard layout doesn’t even support capslock (see the next section) — so I patched it to be a function-lock indicator instead!

Here’s the diff — but do take care if you want to apply similar patches to your laptop! The files I’m editing are under board/hx20 since I’m on an 11th Gen Intel CPU. If you have a different CPU, you will probably need to fuck with different code:

~/board/hx20/board.h
m4_fmt_code(fn-lock-1.diff.html)
~/board/hx20/keyboard-customization.c
m4_fmt_code(fn-lock-2.diff.html)

As you can see, toggling the capslock LED is as simple as invoking gpio_set_level(). Not only that, but disabling its functionality with the capslock key is as easy as undefining the CONFIG_CAPSLOCK_SUPPORT macro. Figuring out if the function key is locked is also really easy. The Fn_key global variable is a bit-field containing information pertaining to the function key, and we also conveniently already have the FN_LOCKED constant defined that we can bitwise-AND with Fn_key to check the locked state!

We also setup some hooks with the DECLARE_HOOK() macro. These just ensure that we are behaving properly on system resume and -suspend.

The Hybrid Key

Wouldn’t it be cool if a physical key could represent two keys at the same time? I thought so too. Like all Emacs users, I suffer from a distinct lack of easily-accessible modifier keys. I need escape because I use Vim bindings; I need left-control because all the Emacs bindings use it; I need super for my window-managers’ bindings; I need left-alt so I can type characters that don’t come on a standard American keyboard (such as ß, , and é), and now I have a problem. All my modifiers are taken, but Emacs still needs a meta key to work!

Workflow by Randall Munroe
XKCD Comic 1172

What will I ever do!? Well thanks to Framework making the EC open-source, and conveniently giving me a file called keyboard_customization.c, I’m going to take two keys and stick them in one! The basic premise is this: the capslock key is arguably the easiest modifier key to hit, and it’s currently bound to the escape key on my system. This is inefficient though, because nobody makes key-bindings that chord the escape-key with another key; chords are always done with a modifier like control, and Emacs is no different. So my plan was to make it so that the capslock key when used on its own mimics an escape-key, while instead mimicking the left-control-key when used in a chord with another key.

It took me a little longer this time to figure out how to implement what I wanted since the code isn’t as clear, but it was still a surprisingly easy feature to patch into the EC! I basically just updated the scancode table, swapping out the capslock scancode for my own random one that I called SCANCODE_CTRL_ESC. I then created a new function called try_ctrl_esc() which is called in the on-keyup and -down callback function. The try_ctrl_esc() function handles all of the logic as you can see in the following diff; it’s basically just a state machine:

~/board/hx20/keyboard_customization.c
m4_fmt_code(hybrid.diff.html)

One thing that’s good to take note of is what I return from try_ctrl_esc(). The general pattern for handling a keyup or -down event is to stick the following code into keyboard_scancode_callback():

keyboard_scancode_callback() in ~/board/hx20/keyboard_customization.c
m4_fmt_code(kbd-sc-cb.c.html)

In my_handler_function() (or whatever you decide to name it), you attempt to handle the event. If you don’t want to handle a particular event and instead want to pass it on to the next handler, you need to return EC_SUCCESS. If you managed to successfully handle the event though, then you need to return an error such as EC_ERROR_UNIMPLEMENTED. It’s pretty stupid and makes very little sense from a naming perspective, but oh well…

What’s Next?

RGB LEDs maybe.