summaryrefslogtreecommitdiffhomepage
path: root/src/blog/fw-ec/index.gsp
blob: acd39b983556e6cb5751d7f5876d20b7d6227bdf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
html lang="en" {
	head { m4_include(head.gsp) }
	body {
		header {
			div {
				h1 {-Framework is Awesome}
				m4_include(nav.gsp)
			}

			figure .quote {
				blockquote {
					p {=
						UNIX was not designed to stop its users from doing stupid things, as
						that would also stop them from doing clever things.
					}
				}
				figcaption {-Doug Gywn}
			}
		}

		main {
			h2 {-Table of Contents}

			ul {
				li {a href="#framework" {-Framework and the EC}}
				li {a href="#led" {-LED Fun!}}
				li {a href="#more" {-There’s More Than One LED‽}}
				li {a href="#hybrid" {-The Hybrid Key}}
				li {a href="#next" {-What’s Next?}}
			}

			h2 #framework {-Framework and the m4_abbr(EC)}
			p {-
				@a href="https://frame.work" target="_blank" {-Framework}
				— for those unaware — is the coolest laptop manufacturer ever.  Their
				whole @em{-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!
			}

			p {-
				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
				@a
					href="https://github.com/FrameworkComputer/EmbeddedController"
					target="_blank"
				{-code for the embedded controller}
				of their laptops, which offers all sorts of possibilities for
				customization of the keyboard, m4_abbr(LED) lights, and more.
			}

			h2 #led {-m4_abbr(LED) Fun!}
			p {-
				This is an area of the m4_abbr(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 m4_abbr(EC) to make the power-button m4_abbr(LED) green instead of
				the normal boring white:
			}

			aside {
				p {-
					Just a tip: if you want to try any of these patches out,
					simply copy the diffs and paste them
					into @code {-git apply}.
				}
			}

			figure {
				figcaption {
					code {-~/board/hx20/led.c}
				}
				pre {= m4_fmt_code(led.diff.gsp) }
			}

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

			h2 #more {-There’s More Than One m4_abbr(LED)‽}
			p {-
				That’s right!  The Framework laptop I own (13″; the 16″ releases soon
				though!) has 3 more m4_abbr(LED) lights.  One on the left of the
				chassis, one on right of the chassis, and one on the capslock key.  The
				capslock m4_abbr(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!
			}

			p {-
				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 @code{-board/hx20}
				since I’m on an 11th Gen Intel m4_abbr(CPU).  If you have a different
				m4_abbr(CPU), you will probably need to fuck with different code:
			}

			figure {
				figcaption {
					code {-~/board/hx20/board.h}
				}
				pre {= m4_fmt_code(fn-lock-1.diff.gsp) }
			}

			figure {
				figcaption {
					code {-~/board/hx20/keyboard-customization.c}
				}
				pre {= m4_fmt_code(fn-lock-2.diff.gsp) }
			}

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

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

			h2 #hybrid {-The Hybrid Key}
			p {-
				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 @em{-ß}, @em{-€}, and @em{-é}), and now I have a problem.  All
				my modifiers are taken, but Emacs still needs a meta key to work!
			}

			figure {
				figcaption {-
					@cite{-Workflow} by Randall Munroe
				}
				img alt="XKCD Comic 1172" src="1172.png" {}
			}

			p {-
				What will I ever do‽  Well thanks to Framework making the m4_abbr(EC)
				open-source, and conveniently giving me a file called
				@code{-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 @x-ref{-1} 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.
			}

			p {-
				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 m4_abbr(EC)!  I basically just updated
				the scancode table, swapping out the capslock scancode for my own random
				one that I called @code{-SCANCODE_CTRL_ESC}.  I then created a new
				function called @code{-try_ctrl_esc()} which is called in the on-keyup
				and -down callback function.  The @code{-try_ctrl_esc()} function
				handles all of the logic as you can see in the following diff; it’s
				basically just a state machine:
			}

			aside {
				p data-ref="1" {-
					If you’re confused by what I mean by a ‘key-chord’, I am simply
					referring to pressing multiple keys in conjunction, such as when you
					press ‘@kbd{-Ctrl + C}’ to copy text.
				}
			}

			figure {
				figcaption {
					code {-~/board/hx20/keyboard_customization.c}
				}
				pre {= m4_fmt_code(hybrid.diff.gsp) }
			}

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

			figure {
				figcaption {-
					@code{-keyboard_scancode_callback()} in
					@code{-~/board/hx20/keyboard_customization.c}
				}
				pre {= m4_fmt_code(kbd-sc-cb.c.gsp) }
			}

			p {-
				In @code{-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 @code{-EC_SUCCESS}.  If you managed to successfully
				handle the event though, then you need to return an error such as
				@code{-EC_ERROR_UNIMPLEMENTED}.  It’s pretty stupid and makes very
				little sense from a naming perspective, but oh well…
			}

			h2 #next {-What’s Next?}
			p {-
				m4_abbr(RGB) m4_abbr(LED)s maybe.
			}
		}

		hr{}
		
		footer { m4_footer }
	}
}