chore(): QMK Firmware blog post
This commit is contained in:
parent
edfc9d06ac
commit
1b299171ad
2 changed files with 691 additions and 0 deletions
|
@ -4782,6 +4782,350 @@ So I decided to make the whole API as accessible as possible from the command li
|
|||
All I got to say in conclusion is that it was a lot of fun working on [[https://gitea.project42.io/Elia/cmw][cmw]] and I learned a lot.
|
||||
I'm not going to publish the package on [[https://pypi.org/][PyPI]] because seriously, what's the point.
|
||||
But if you are interested in making changes to the repository, make an MR.
|
||||
*** DONE QMK Firmware :qmk:firmware:mechanical_keyboard:qmk_firmware:
|
||||
:PROPERTIES:
|
||||
:EXPORT_HUGO_LASTMOD: 2021-09-23
|
||||
:EXPORT_DATE: 2021-09-23
|
||||
:EXPORT_FILE_NAME: qmk-firmware
|
||||
:CUSTOM_ID: qmk-firmware
|
||||
:END:
|
||||
|
||||
Over the years, I have owned a few mechanical keyboards. I'm quite fond of them.
|
||||
I've also built my own keyboard from scratch years ago. Hot-swappable back then
|
||||
was still in its easy stages and the sockets weren't that good. Alas, we're in
|
||||
2021 and I've recently purchased the *Keychron Q1* keyboard.
|
||||
|
||||
I've chosen this keyboard for many reasons, but the one you most care about is
|
||||
the topic that brought you here. It's a *QMK Firmware* compatible keyboards. Do
|
||||
you know what that means ?
|
||||
|
||||
That means that we're going to be digging into ~qmk_firmware~. Tag along !
|
||||
|
||||
#+hugo: more
|
||||
|
||||
**** Quantum Mechanical Keyboard Firmware
|
||||
|
||||
The [[https://github.com/qmk/qmk_firmware][*QMK Firmware*]] is
|
||||
|
||||
#+begin_quote
|
||||
a keyboard firmware based on the tmk_keyboard firmware with some useful features
|
||||
for Atmel AVR and ARM controllers, and more specifically, the OLKB product line,
|
||||
the ErgoDox EZ keyboard, and the Clueboard product line.
|
||||
#+end_quote
|
||||
|
||||
It goes beyond saying, the *QMK Firmware* is open sourced. So let's hack it.
|
||||
|
||||
**** Building QMK Firmware
|
||||
|
||||
The first step to flashing your keyboard starts here. We need to get the source
|
||||
code of ~qmk_firmware~ from Github.
|
||||
|
||||
#+begin_src shell
|
||||
$ git clone https://github.com/qmk/qmk_firmware.git
|
||||
# Wait a while...
|
||||
# Yup, I know !
|
||||
# Okay finally...
|
||||
Cloning into 'qmk_firmware'...
|
||||
remote: Enumerating objects: 295442, done.
|
||||
remote: Counting objects: 100% (34/34), done.
|
||||
remote: Compressing objects: 100% (27/27), done.
|
||||
remote: Total 295442 (delta 13), reused 17 (delta 5), pack-reused 295408
|
||||
Receiving objects: 100% (295442/295442), 178.92 MiB | 7.10 MiB/s, done.
|
||||
Resolving deltas: 100% (178414/178414), done.
|
||||
Updating files: 100% (27916/27916), done.
|
||||
|
||||
$ cd qmk_firmware
|
||||
#+end_src
|
||||
|
||||
Once the repository is clone, we can start with installing the dependencies to
|
||||
build ~qmk~.
|
||||
|
||||
I'm not a big fan of auto-installers or installers scripts
|
||||
(=util/install/arch.sh=), and here's why.
|
||||
|
||||
#+begin_src bash
|
||||
python3 -m pip install --user -r $QMK_FIRMWARE_DIR/requirements.txt
|
||||
#+end_src
|
||||
|
||||
This is how the installer of the ~qmk_firmware~ concludes the round. I would
|
||||
hate to use pip to install willy nilly like that.
|
||||
|
||||
Otherwise, I don't have objections to what it does on ~arch~ at least.
|
||||
|
||||
It does the following, I see no reason not to follow it.
|
||||
|
||||
#+begin_src shell
|
||||
$ sudo pacman -S \
|
||||
base-devel clang diffutils gcc git unzip wget zip python-pip \
|
||||
avr-binutils arm-none-eabi-binutils arm-none-eabi-gcc \
|
||||
arm-none-eabi-newlib avrdude dfu-programmer dfu-util
|
||||
$ sudo pacman -U https://archive.archlinux.org/packages/a/avr-gcc/avr-gcc-8.3.0-1-x86_64.pkg.tar.xz
|
||||
$ sudo pacman -S avr-libc # Must be installed after the above, or it will bring in the latest avr-gcc instead
|
||||
$ sudo pacman -S hidapi # This will fail if the community repo isn't enabled
|
||||
#+end_src
|
||||
|
||||
Now that all the dependencies required by the system are installed, let's
|
||||
install the ~python~ dependencies.
|
||||
|
||||
#+begin_src shell
|
||||
$ git checkout 0.14.9 # Checkout the latest version
|
||||
$ vf new qmk_firmware # Create a new python virtualenv and activate it
|
||||
$ pip install -r requirements.txt # Install python requirements
|
||||
$ pip install qmk
|
||||
$ make git-submodule
|
||||
#+end_src
|
||||
|
||||
Finally, we can build our keyboard firmware.
|
||||
|
||||
#+begin_src bash
|
||||
$ qmk compile -kb keychron/q1/rev_0100 -km default
|
||||
Ψ Compiling keymap with make --jobs=1 keychron/q1/rev_0100:default [31/494]
|
||||
|
||||
|
||||
QMK Firmware 0.14.16
|
||||
Making keychron/q1/rev_0100 with keymap default
|
||||
|
||||
avr-gcc (GCC) 11.2.0
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Compiling: keyboards/keychron/q1/q1.c [OK]
|
||||
Compiling: keyboards/keychron/q1/rev_0100/rev_0100.c [OK]
|
||||
Compiling: keyboards/keychron/q1/rev_0100/keymaps/default/keymap.c [OK]
|
||||
Compiling: quantum/quantum.c [OK]
|
||||
Compiling: quantum/send_string.c [OK]
|
||||
Compiling: quantum/bitwise.c [OK]
|
||||
Compiling: quantum/led.c [OK]
|
||||
Compiling: quantum/action.c [OK]
|
||||
Compiling: quantum/action_layer.c [OK]
|
||||
Compiling: quantum/action_macro.c [OK]
|
||||
Compiling: quantum/action_tapping.c [OK]
|
||||
Compiling: quantum/action_util.c [OK]
|
||||
Compiling: quantum/eeconfig.c [OK]
|
||||
Compiling: quantum/keyboard.c [OK]
|
||||
Compiling: quantum/keymap_common.c [OK]
|
||||
Compiling: quantum/keycode_config.c [OK]
|
||||
Compiling: quantum/logging/debug.c [OK]
|
||||
Compiling: quantum/logging/sendchar.c [OK]
|
||||
Compiling: quantum/bootmagic/bootmagic_lite.c [OK]
|
||||
Compiling: quantum/bootmagic/magic.c [OK]
|
||||
Compiling: quantum/matrix_common.c [OK]
|
||||
Compiling: quantum/matrix.c [OK]
|
||||
Compiling: quantum/debounce/sym_defer_g.c [OK]
|
||||
Compiling: quantum/main.c [OK]
|
||||
Compiling: quantum/color.c [OK]
|
||||
Compiling: quantum/rgb_matrix/rgb_matrix.c [OK]
|
||||
Compiling: quantum/rgb_matrix/rgb_matrix_drivers.c [OK]
|
||||
Compiling: lib/lib8tion/lib8tion.c [OK]
|
||||
Compiling: drivers/led/issi/is31fl3733.c [OK]
|
||||
Compiling: quantum/process_keycode/process_rgb.c [OK]
|
||||
Compiling: quantum/led_tables.c [OK]
|
||||
Compiling: quantum/dip_switch.c [OK]
|
||||
Compiling: quantum/process_keycode/process_space_cadet.c [OK]
|
||||
Compiling: quantum/process_keycode/process_magic.c [OK]
|
||||
Compiling: quantum/process_keycode/process_grave_esc.c [OK]
|
||||
Compiling: platforms/avr/drivers/i2c_master.c [OK]
|
||||
Archiving: .build/obj_keychron_q1_rev_0100_default/i2c_master.o [OK]
|
||||
Compiling: tmk_core/common/host.c [OK]
|
||||
Compiling: tmk_core/common/report.c [OK]
|
||||
Compiling: tmk_core/common/sync_timer.c [OK]
|
||||
Compiling: tmk_core/common/usb_util.c [OK]
|
||||
Compiling: tmk_core/common/avr/platform.c [OK]
|
||||
Compiling: tmk_core/common/avr/suspend.c [OK]
|
||||
Compiling: tmk_core/common/avr/timer.c [OK]
|
||||
Compiling: tmk_core/common/avr/bootloader.c [OK]
|
||||
Assembling: tmk_core/common/avr/xprintf.S [OK]
|
||||
Compiling: tmk_core/common/avr/printf.c [OK]
|
||||
Compiling: tmk_core/protocol/lufa/lufa.c [OK]
|
||||
Compiling: tmk_core/protocol/usb_descriptor.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/ConfigDescriptors.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/DeviceStandardReq.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/Events.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/HostStandardReq.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/USBTask.c [OK]
|
||||
Compiling: tmk_core/protocol/lufa/usb_util.c [OK]
|
||||
Linking: .build/keychron_q1_rev_0100_default.elf [OK]
|
||||
Creating load file for flashing: .build/keychron_q1_rev_0100_default.hex [OK]
|
||||
Copying keychron_q1_rev_0100_default.hex to qmk_firmware folder [OK]
|
||||
Checking file size of keychron_q1_rev_0100_default.hex [OK]
|
||||
* The firmware size is fine - 23302/28672 (81%, 5370 bytes free)
|
||||
|
||||
#+end_src
|
||||
|
||||
Look at tha, easy as pie ! You got yourself a compiled firmware.
|
||||
|
||||
Before we move on, let's look at the command again and figure out what the hell
|
||||
I did, just in case you're running a different keyboard.
|
||||
|
||||
If you look into the =keyboards/=, you'll be able to find a big list of
|
||||
keyboards supported. The =keychron/q1/rev_0100= is simply a directory in there
|
||||
that matches my keyboard. Inside that directory, we can find the =keymaps/=
|
||||
directory. This is where all the keymaps live. We chose the ~default~ keymap
|
||||
which is a directory in there as well.
|
||||
|
||||
**** Remapping the keyboard
|
||||
|
||||
At this stage, we were able to succesfully compile the keyboard firmware. But
|
||||
the whole point of this is to modify the layout of the keyboard so let's go
|
||||
right ahead.
|
||||
|
||||
There are commands suggested on the ~QMK~ docs but I didn't go that far, I
|
||||
simply copied the =default= directory and went down to business. For the sake of
|
||||
this blog post, I'll assume I called the directory =functions=.
|
||||
|
||||
The =keymap.c= file looks as follows.
|
||||
|
||||
#+begin_src c
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers{
|
||||
MAC_BASE,
|
||||
MAC_FN,
|
||||
WIN_BASE,
|
||||
WIN_FN
|
||||
};
|
||||
|
||||
#define KC_TASK LGUI(KC_TAB)
|
||||
#define KC_FLXP LGUI(KC_E)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[MAC_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_BRID, KC_BRIU, KC_F3, KC_F4, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[MAC_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
||||
|
||||
[WIN_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[WIN_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
|
||||
|
||||
};
|
||||
#+end_src
|
||||
|
||||
If you read this you will understand that the keyboard originally comes with 4
|
||||
layers. Two for windows and two for Mac. The ~0~ and ~1~ layers are toggled
|
||||
using a physical switch. The rest are toggled with the ~Fn~ key.
|
||||
|
||||
Now let's change the Mac layout to have the ~Function~ keys to be on the main
|
||||
layer while the media keys to be toggled with the ~Fn~ key. The final version
|
||||
should look like the following.
|
||||
|
||||
#+begin_src c
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers{
|
||||
MAC_BASE,
|
||||
MAC_FN,
|
||||
WIN_BASE,
|
||||
WIN_FN
|
||||
};
|
||||
|
||||
#define KC_TASK LGUI(KC_TAB)
|
||||
#define KC_FLXP LGUI(KC_E)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[MAC_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[MAC_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_F3, KC_F4, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
||||
|
||||
[WIN_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[WIN_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
|
||||
|
||||
};
|
||||
#+end_src
|
||||
|
||||
Now that that's done, we need to compile to check that we didn't forget
|
||||
anything.
|
||||
|
||||
#+begin_src shell
|
||||
$ qmk compile -kb keychron/q1/rev_0100 -km functions
|
||||
#+end_src
|
||||
|
||||
We seem to have successfully compiled our now keyboard layout.
|
||||
|
||||
**** Flashing your keyboard
|
||||
|
||||
If you're reached this stage, you'll need to locate the ~reset~ button on your
|
||||
keyboard. Once located, follow your keyboard's manual on how to *reset* the
|
||||
board and getting ready it for flashing.
|
||||
|
||||
Once the keyboard is ready to be flashed, you basically change one thing in your
|
||||
previous command.
|
||||
|
||||
#+begin_src shell
|
||||
$ qmk flash -kb keychron/q1/rev_0100 -km functions
|
||||
#+end_src
|
||||
|
||||
If this step succeeds, your keyboard should be ready to use in the newly
|
||||
configured layout. Check it out !
|
||||
|
||||
**** Conclusion
|
||||
|
||||
It's pretty awesome to see keyboards like these hit the market. Whether you're
|
||||
fan of the mechanical switches they come with or not, one thing is certain. You
|
||||
cannot deny the fact that they are very customisable. If you don't like
|
||||
something with your keyboard, simply change it. The beauty of it all is that the
|
||||
firmware is open sourced. The community delivers, yet again !
|
||||
|
||||
** Monitoring :@monitoring:
|
||||
*** DONE Simple cron monitoring with HealthChecks :healthchecks:cron:
|
||||
:PROPERTIES:
|
||||
|
|
347
content/posts/qmk-firmware.md
Normal file
347
content/posts/qmk-firmware.md
Normal file
|
@ -0,0 +1,347 @@
|
|||
+++
|
||||
title = "QMK Firmware"
|
||||
author = ["Elia el Lazkani"]
|
||||
date = 2021-09-23
|
||||
lastmod = 2021-09-23
|
||||
tags = ["qmk", "firmware", "mechanical-keyboard", "qmk-firmware"]
|
||||
categories = ["misc"]
|
||||
draft = false
|
||||
+++
|
||||
|
||||
Over the years, I have owned a few mechanical keyboards. I'm quite fond of them.
|
||||
I've also built my own keyboard from scratch years ago. Hot-swappable back then
|
||||
was still in its easy stages and the sockets weren't that good. Alas, we're in
|
||||
2021 and I've recently purchased the **Keychron Q1** keyboard.
|
||||
|
||||
I've chosen this keyboard for many reasons, but the one you most care about is
|
||||
the topic that brought you here. It's a **QMK Firmware** compatible keyboards. Do
|
||||
you know what that means ?
|
||||
|
||||
That means that we're going to be digging into `qmk_firmware`. Tag along !
|
||||
|
||||
<!--more-->
|
||||
|
||||
|
||||
## Quantum Mechanical Keyboard Firmware {#quantum-mechanical-keyboard-firmware}
|
||||
|
||||
The [**QMK Firmware**](https://github.com/qmk/qmk%5Ffirmware) is
|
||||
|
||||
> a keyboard firmware based on the tmk\_keyboard firmware with some useful features
|
||||
> for Atmel AVR and ARM controllers, and more specifically, the OLKB product line,
|
||||
> the ErgoDox EZ keyboard, and the Clueboard product line.
|
||||
|
||||
It goes beyond saying, the **QMK Firmware** is open sourced. So let's hack it.
|
||||
|
||||
|
||||
## Building QMK Firmware {#building-qmk-firmware}
|
||||
|
||||
The first step to flashing your keyboard starts here. We need to get the source
|
||||
code of `qmk_firmware` from Github.
|
||||
|
||||
```shell
|
||||
$ git clone https://github.com/qmk/qmk_firmware.git
|
||||
# Wait a while...
|
||||
# Yup, I know !
|
||||
# Okay finally...
|
||||
Cloning into 'qmk_firmware'...
|
||||
remote: Enumerating objects: 295442, done.
|
||||
remote: Counting objects: 100% (34/34), done.
|
||||
remote: Compressing objects: 100% (27/27), done.
|
||||
remote: Total 295442 (delta 13), reused 17 (delta 5), pack-reused 295408
|
||||
Receiving objects: 100% (295442/295442), 178.92 MiB | 7.10 MiB/s, done.
|
||||
Resolving deltas: 100% (178414/178414), done.
|
||||
Updating files: 100% (27916/27916), done.
|
||||
|
||||
$ cd qmk_firmware
|
||||
```
|
||||
|
||||
Once the repository is clone, we can start with installing the dependencies to
|
||||
build `qmk`.
|
||||
|
||||
I'm not a big fan of auto-installers or installers scripts
|
||||
(`util/install/arch.sh`), and here's why.
|
||||
|
||||
```bash
|
||||
python3 -m pip install --user -r $QMK_FIRMWARE_DIR/requirements.txt
|
||||
```
|
||||
|
||||
This is how the installer of the `qmk_firmware` concludes the round. I would
|
||||
hate to use pip to install willy nilly like that.
|
||||
|
||||
Otherwise, I don't have objections to what it does on `arch` at least.
|
||||
|
||||
It does the following, I see no reason not to follow it.
|
||||
|
||||
```shell
|
||||
$ sudo pacman -S \
|
||||
base-devel clang diffutils gcc git unzip wget zip python-pip \
|
||||
avr-binutils arm-none-eabi-binutils arm-none-eabi-gcc \
|
||||
arm-none-eabi-newlib avrdude dfu-programmer dfu-util
|
||||
$ sudo pacman -U https://archive.archlinux.org/packages/a/avr-gcc/avr-gcc-8.3.0-1-x86_64.pkg.tar.xz
|
||||
$ sudo pacman -S avr-libc # Must be installed after the above, or it will bring in the latest avr-gcc instead
|
||||
$ sudo pacman -S hidapi # This will fail if the community repo isn't enabled
|
||||
```
|
||||
|
||||
Now that all the dependencies required by the system are installed, let's
|
||||
install the `python` dependencies.
|
||||
|
||||
```shell
|
||||
$ git checkout 0.14.9 # Checkout the latest version
|
||||
$ vf new qmk_firmware # Create a new python virtualenv and activate it
|
||||
$ pip install -r requirements.txt # Install python requirements
|
||||
$ pip install qmk
|
||||
$ make git-submodule
|
||||
```
|
||||
|
||||
Finally, we can build our keyboard firmware.
|
||||
|
||||
```bash
|
||||
$ qmk compile -kb keychron/q1/rev_0100 -km default
|
||||
Ψ Compiling keymap with make --jobs=1 keychron/q1/rev_0100:default [31/494]
|
||||
|
||||
|
||||
QMK Firmware 0.14.16
|
||||
Making keychron/q1/rev_0100 with keymap default
|
||||
|
||||
avr-gcc (GCC) 11.2.0
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Compiling: keyboards/keychron/q1/q1.c [OK]
|
||||
Compiling: keyboards/keychron/q1/rev_0100/rev_0100.c [OK]
|
||||
Compiling: keyboards/keychron/q1/rev_0100/keymaps/default/keymap.c [OK]
|
||||
Compiling: quantum/quantum.c [OK]
|
||||
Compiling: quantum/send_string.c [OK]
|
||||
Compiling: quantum/bitwise.c [OK]
|
||||
Compiling: quantum/led.c [OK]
|
||||
Compiling: quantum/action.c [OK]
|
||||
Compiling: quantum/action_layer.c [OK]
|
||||
Compiling: quantum/action_macro.c [OK]
|
||||
Compiling: quantum/action_tapping.c [OK]
|
||||
Compiling: quantum/action_util.c [OK]
|
||||
Compiling: quantum/eeconfig.c [OK]
|
||||
Compiling: quantum/keyboard.c [OK]
|
||||
Compiling: quantum/keymap_common.c [OK]
|
||||
Compiling: quantum/keycode_config.c [OK]
|
||||
Compiling: quantum/logging/debug.c [OK]
|
||||
Compiling: quantum/logging/sendchar.c [OK]
|
||||
Compiling: quantum/bootmagic/bootmagic_lite.c [OK]
|
||||
Compiling: quantum/bootmagic/magic.c [OK]
|
||||
Compiling: quantum/matrix_common.c [OK]
|
||||
Compiling: quantum/matrix.c [OK]
|
||||
Compiling: quantum/debounce/sym_defer_g.c [OK]
|
||||
Compiling: quantum/main.c [OK]
|
||||
Compiling: quantum/color.c [OK]
|
||||
Compiling: quantum/rgb_matrix/rgb_matrix.c [OK]
|
||||
Compiling: quantum/rgb_matrix/rgb_matrix_drivers.c [OK]
|
||||
Compiling: lib/lib8tion/lib8tion.c [OK]
|
||||
Compiling: drivers/led/issi/is31fl3733.c [OK]
|
||||
Compiling: quantum/process_keycode/process_rgb.c [OK]
|
||||
Compiling: quantum/led_tables.c [OK]
|
||||
Compiling: quantum/dip_switch.c [OK]
|
||||
Compiling: quantum/process_keycode/process_space_cadet.c [OK]
|
||||
Compiling: quantum/process_keycode/process_magic.c [OK]
|
||||
Compiling: quantum/process_keycode/process_grave_esc.c [OK]
|
||||
Compiling: platforms/avr/drivers/i2c_master.c [OK]
|
||||
Archiving: .build/obj_keychron_q1_rev_0100_default/i2c_master.o [OK]
|
||||
Compiling: tmk_core/common/host.c [OK]
|
||||
Compiling: tmk_core/common/report.c [OK]
|
||||
Compiling: tmk_core/common/sync_timer.c [OK]
|
||||
Compiling: tmk_core/common/usb_util.c [OK]
|
||||
Compiling: tmk_core/common/avr/platform.c [OK]
|
||||
Compiling: tmk_core/common/avr/suspend.c [OK]
|
||||
Compiling: tmk_core/common/avr/timer.c [OK]
|
||||
Compiling: tmk_core/common/avr/bootloader.c [OK]
|
||||
Assembling: tmk_core/common/avr/xprintf.S [OK]
|
||||
Compiling: tmk_core/common/avr/printf.c [OK]
|
||||
Compiling: tmk_core/protocol/lufa/lufa.c [OK]
|
||||
Compiling: tmk_core/protocol/usb_descriptor.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Class/Common/HIDParser.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/ConfigDescriptors.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/DeviceStandardReq.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/Events.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/HostStandardReq.c [OK]
|
||||
Compiling: lib/lufa/LUFA/Drivers/USB/Core/USBTask.c [OK]
|
||||
Compiling: tmk_core/protocol/lufa/usb_util.c [OK]
|
||||
Linking: .build/keychron_q1_rev_0100_default.elf [OK]
|
||||
Creating load file for flashing: .build/keychron_q1_rev_0100_default.hex [OK]
|
||||
Copying keychron_q1_rev_0100_default.hex to qmk_firmware folder [OK]
|
||||
Checking file size of keychron_q1_rev_0100_default.hex [OK]
|
||||
* The firmware size is fine - 23302/28672 (81%, 5370 bytes free)
|
||||
```
|
||||
|
||||
Look at tha, easy as pie ! You got yourself a compiled firmware.
|
||||
|
||||
Before we move on, let's look at the command again and figure out what the hell
|
||||
I did, just in case you're running a different keyboard.
|
||||
|
||||
If you look into the `keyboards/`, you'll be able to find a big list of
|
||||
keyboards supported. The `keychron/q1/rev_0100` is simply a directory in there
|
||||
that matches my keyboard. Inside that directory, we can find the `keymaps/`
|
||||
directory. This is where all the keymaps live. We chose the `default` keymap
|
||||
which is a directory in there as well.
|
||||
|
||||
|
||||
## Remapping the keyboard {#remapping-the-keyboard}
|
||||
|
||||
At this stage, we were able to succesfully compile the keyboard firmware. But
|
||||
the whole point of this is to modify the layout of the keyboard so let's go
|
||||
right ahead.
|
||||
|
||||
There are commands suggested on the `QMK` docs but I didn't go that far, I
|
||||
simply copied the `default` directory and went down to business. For the sake of
|
||||
this blog post, I'll assume I called the directory `functions`.
|
||||
|
||||
The `keymap.c` file looks as follows.
|
||||
|
||||
```c
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers{
|
||||
MAC_BASE,
|
||||
MAC_FN,
|
||||
WIN_BASE,
|
||||
WIN_FN
|
||||
};
|
||||
|
||||
#define KC_TASK LGUI(KC_TAB)
|
||||
#define KC_FLXP LGUI(KC_E)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[MAC_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_BRID, KC_BRIU, KC_F3, KC_F4, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[MAC_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
||||
|
||||
[WIN_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[WIN_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
If you read this you will understand that the keyboard originally comes with 4
|
||||
layers. Two for windows and two for Mac. The `0` and `1` layers are toggled
|
||||
using a physical switch. The rest are toggled with the `Fn` key.
|
||||
|
||||
Now let's change the Mac layout to have the `Function` keys to be on the main
|
||||
layer while the media keys to be toggled with the `Fn` key. The final version
|
||||
should look like the following.
|
||||
|
||||
```c
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers{
|
||||
MAC_BASE,
|
||||
MAC_FN,
|
||||
WIN_BASE,
|
||||
WIN_FN
|
||||
};
|
||||
|
||||
#define KC_TASK LGUI(KC_TAB)
|
||||
#define KC_FLXP LGUI(KC_E)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[MAC_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[MAC_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_F3, KC_F4, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
||||
|
||||
[WIN_BASE] = LAYOUT_ansi_82(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_PGUP,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_HOME,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[WIN_FN] = LAYOUT_ansi_82(
|
||||
KC_TRNS, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
Now that that's done, we need to compile to check that we didn't forget
|
||||
anything.
|
||||
|
||||
```shell
|
||||
$ qmk compile -kb keychron/q1/rev_0100 -km functions
|
||||
```
|
||||
|
||||
We seem to have successfully compiled our now keyboard layout.
|
||||
|
||||
|
||||
## Flashing your keyboard {#flashing-your-keyboard}
|
||||
|
||||
If you're reached this stage, you'll need to locate the `reset` button on your
|
||||
keyboard. Once located, follow your keyboard's manual on how to **reset** the
|
||||
board and getting ready it for flashing.
|
||||
|
||||
Once the keyboard is ready to be flashed, you basically change one thing in your
|
||||
previous command.
|
||||
|
||||
```shell
|
||||
$ qmk flash -kb keychron/q1/rev_0100 -km functions
|
||||
```
|
||||
|
||||
If this step succeeds, your keyboard should be ready to use in the newly
|
||||
configured layout. Check it out !
|
||||
|
||||
|
||||
## Conclusion {#conclusion}
|
||||
|
||||
It's pretty awesome to see keyboards like these hit the market. Whether you're
|
||||
fan of the mechanical switches they come with or not, one thing is certain. You
|
||||
cannot deny the fact that they are very customisable. If you don't like
|
||||
something with your keyboard, simply change it. The beauty of it all is that the
|
||||
firmware is open sourced. The community delivers, yet again !
|
Loading…
Reference in a new issue