From 4d6857993ea9f39ff4113809fd7b2272ff83647f Mon Sep 17 00:00:00 2001
From: Thomas Voss
+
+
+
+
@@ -218,7 +218,6 @@
+ #define CONFIG_CMD_LEDTEST
+ #define CONFIG_LED_PWM_COUNT 3
+ #define CONFIG_LED_PWM_TASK_DISABLED
+-#define CONFIG_CAPSLED_SUPPORT
+
+
#ifdef CONFIG_ACCEL_KX022
+ #define CONFIG_LID_ANGLE
diff --git a/src/srp/fw-ec/fn-lock-2.diff.html b/src/srp/fw-ec/fn-lock-2.diff.html
new file mode 100644
index 0000000..b3880e0
--- /dev/null
+++ b/src/srp/fw-ec/fn-lock-2.diff.html
@@ -0,0 +1,36 @@
+
+
+
+
+
@@ -249,6 +249,23 @@ int fn_table_set(int8_t pressed, uint32_t fn_bit)
+ return false;
+ }
+
+
+static void hx20_update_fnkey_led(void) {
++ /* Turn the capslock light into a fn-lock light */
++ gpio_set_level(GPIO_CAP_LED_L, (Fn_key & FN_LOCKED) ? 1 : 0);
++}
++
++/* Set the fn-lock light to the correct setting when the system resumes */
++void hx20_fnkey_resume(void) {
++ hx20_update_fnkey_led();
++}
++DECLARE_HOOK(HOOK_CHIPSET_RESUME, hx20_fnkey_resume, HOOK_PRIO_DEFAULT);
++
++/* Disable the fn-lock light on suspend */
++void hx20_fnkey_suspend(void) {
++ gpio_set_level(GPIO_CAP_LED_L, 0);
++}
++DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, hx20_fnkey_suspend, HOOK_PRIO_DEFAULT);
++
+ void fnkey_shutdown(void) {
+ uint8_t current_kb = 0;
+
+
@@ -420,6 +437,7 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)
+ Fn_key &= ~FN_LOCKED;
+ else
+ Fn_key |= FN_LOCKED;
++ hx20_update_fnkey_led();
+ }
+ return EC_ERROR_UNIMPLEMENTED;
+ }
diff --git a/src/srp/fw-ec/hybrid.diff.html b/src/srp/fw-ec/hybrid.diff.html
new file mode 100644
index 0000000..a37d3b5
--- /dev/null
+++ b/src/srp/fw-ec/hybrid.diff.html
@@ -0,0 +1,88 @@
+
+
+
+
+
@@ -22,12 +22,15 @@
+ #define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args)
+ #define CPRINTF(format, args...) cprintf(CC_KEYBOARD, format, ## args)
+
+
+/* The scancode for the caps-lock key, which is now a hybrid key */
++#define SCANCODE_CTRL_ESC 0x0101
++
+ uint16_t scancode_set2[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = {
+ {0x0021, 0x007B, 0x0079, 0x0072, 0x007A, 0x0071, 0x0069, 0xe04A},
+ {0xe071, 0xe070, 0x007D, 0xe01f, 0x006c, 0xe06c, 0xe07d, 0x0077},
+ {0x0015, 0x0070, 0x00ff, 0x000D, 0x000E, 0x0016, 0x0067, 0x001c},
+ {0xe011, 0x0011, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+- {0xe05a, 0x0029, 0x0024, 0x000c, 0x0058, 0x0026, 0x0004, 0xe07a},
++ {0xe05a, 0x0029, 0x0024, 0x000c, 0x0101, 0x0026, 0x0004, 0xe07a},
+ {0x0022, 0x001a, 0x0006, 0x0005, 0x001b, 0x001e, 0x001d, 0x0076},
+ {0x002A, 0x0032, 0x0034, 0x002c, 0x002e, 0x0025, 0x002d, 0x002b},
+ {0x003a, 0x0031, 0x0033, 0x0035, 0x0036, 0x003d, 0x003c, 0x003b},
+@@ -497,6 +500,55 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)
+ return EC_SUCCESS;
+ }
+
+
+int try_ctrl_esc(uint16_t *key_code, int8_t pressed) {
++ static enum {
++ NONE,
++ HELD,
++ CTRL
++ } ctrl_esc_state;
++
++ if (*key_code == SCANCODE_CTRL_ESC) {
++ /* If we pressed the caps key, enter the HELD state. Otherwise,
++ * we are either releasing from the HELD state or the CTRL
++ * state. In both cases we should reset the state to NONE, but
++ * when releasing from the HELD state we want to send an ESC and
++ * when releasing from the CTRL state we want to end the CTRL.
++ *
++ * Also important to note is that even before we know if we’re
++ * going to be acting as ESC or CTRL, we need to send a press-
++ * event of the CTRL key because you can chord CTRL with mouse-
++ * clicks too, not just other keys.
++ */
++ if (pressed) {
++ ctrl_esc_state = HELD;
++ simulate_keyboard(SCANCODE_LEFT_CTRL, 1);
++ } else if (ctrl_esc_state == HELD) {
++ ctrl_esc_state = NONE;
++ simulate_keyboard(SCANCODE_LEFT_CTRL, 0);
++ simulate_keyboard(SCANCODE_ESC, 1);
++ simulate_keyboard(SCANCODE_ESC, 0);
++ } else if (ctrl_esc_state == CTRL) {
++ ctrl_esc_state = NONE;
++ simulate_keyboard(SCANCODE_LEFT_CTRL, 0);
++ }
++
++ return EC_ERROR_UNIMPLEMENTED;
++ }
++
++ /* If we get here then we are dealing with a key that isn’t the caps
++ * key. In that case we need to handle all 3 states. If the state is
++ * NONE then we can just exit from this function. If it’s HELD and we
++ * are pressing a key, then that’s a key-chord and we need to start a
++ * CTRL. Finally, if we are in the CTRL state, there is nothing to do.
++ */
++ if (ctrl_esc_state == HELD && pressed) {
++ ctrl_esc_state = CTRL;
++ simulate_keyboard(SCANCODE_LEFT_CTRL, 1);
++ }
++
++ return EC_SUCCESS;
++}
++
+ enum ec_error_list keyboard_scancode_callback(uint16_t *make_code,
+ int8_t pressed)
+ {
+@@ -521,6 +573,10 @@ enum ec_error_list keyboard_scancode_callback(uint16_t *make_code,
+ if (!pos_get_state())
+ return EC_SUCCESS;
+
+
+ r = try_ctrl_esc(make_code, pressed);
++ if (r != EC_SUCCESS)
++ return r;
++
+ r = hotkey_F1_F12(make_code, Fn_key, pressed);
+ if (r != EC_SUCCESS)
+ return r;
diff --git a/src/srp/fw-ec/index.html b/src/srp/fw-ec/index.html
index d8a48ba..cdfc8b5 100644
--- a/src/srp/fw-ec/index.html
+++ b/src/srp/fw-ec/index.html
@@ -87,6 +87,161 @@
tuples which is awesome, because it opens the door to
custom RGB effects in the future!
+ 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:
+
+ 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.
+
+ 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! +
+ + +
+ 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:
+
+ 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()
:
+
+ 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…
+
+ RGB + LEDs + maybe. +
/* “make_code” is the scancode. “pressed” is a boolean that is true if this is a
+ * keydown event, and false if it’s a keyup.
+ */
+
+r = my_handler_function(make_code, pressed);
+if (r != EC_SUCCESS)
+ return r;
diff --git a/src/style.css b/src/style.css
index 2b67620..45ac7df 100644
--- a/src/style.css
+++ b/src/style.css
@@ -7,6 +7,7 @@
--accent: #DE935F;
--lesser: #969896;
--green: #B5BD68;
+ --blue: #81A2BE;
--red: #C66;
}
@@ -83,7 +84,6 @@ aside {
font-style: italic;
color: var(--lesser);
position: relative;
- margin-block: 1.5rem;
}
aside > p::before,
@@ -123,16 +123,12 @@ abbr::before {
pointer-events: none;
}
+abbr.cpu::before { content: 'Central Processing Unit'; }
abbr.ec::before { content: 'Embedded Controller'; }
abbr.html::before { content: 'Hypertext Markup Language'; }
abbr.led::before { content: 'Light-Emitting Diode'; }
abbr.rgb::before { content: 'Red Green Blue'; }
-.diff-ins { color: var(--green); }
-.diff-del { color: var(--red); }
-.diff-loc { color: var(--lesser); }
-.diff-meta { font-weight: bold; }
-
figure > pre { margin-left: 4ch; overflow-x: scroll; }
figure > pre > code { counter-increment: line; }
figure > pre > code::before {
@@ -149,6 +145,12 @@ figure > pre > code::before {
background-color: var(--bg);
}
+figure > img {
+ display: block;
+ margin: 16px auto;
+ width: 50%;
+}
+
header > div {
display: flex;
justify-content: space-between;
@@ -160,3 +162,12 @@ header > div menu {
gap: 2ch;
}
header > div li { list-style: none; }
+
+.c-cmt { color: var(--lesser); }
+.c-fn { color: var(--accent); }
+.c-kw { color: var(--green); }
+.c-pp { color: var(--blue); }
+.diff-ins { color: var(--green); }
+.diff-del { color: var(--red); }
+.diff-loc { color: var(--lesser); }
+.diff-meta { font-weight: bold; }
--
cgit v1.2.3