QMK Install & Keymap Guide for GMMK 2 Compact | on Ubuntu distros

Dear GMMK community and fans,

Here is my step-by-step guide for installing QMK firmware and setting your own keymap on GMMK 2 Compact.

Context

  1. This guide is applicable to Ubuntu based Linux distros like Pop!_OS 22.04, the one I’m using for years.
  2. QMK CLI is used, since it’s reliable and on Linux QMK Toolbox is not available.

Intro

  • After spending some hours, I managed to have it working. Now, let me share all my notes while discovering features, issues, and solving them.
    • I’m writing this using my newest acquisition, the GMMK 2 Compact
    • Now it has QMK firmware since this allows me to have my own keys, as you’ll see below.
  • I’m using the lovely Pop!_OS linux distro on my machines, so this guide is based on this setup.
  • I gain some “experience” doing this while setting QMK firmware on my GMMK Pro keyboards, although there the process is way smoother than this one.

The main structure follows the “official” GMMK 2: QMK Installation Guide blog post. I’m just adding here some missing parts and additional details.

In the example outputs included below, I tend to skip the unrelevant details by including a ... (ellipsys symbol) to illustrate that some content is omitted. Like this:

one line
   ...
another line

Setting Up

Prerequisites

As stated in Prepare your build environment section, install:

  1. The prerequisites using sudo apt install -y git python3-pip
  2. QMK CLI using python3 -m pip install --user qmk
    (to reinstall it, use python3 -m pip install --ignore-installed --user qmk)

The CLI is the qmk utility that get’s installed in ~/.local/bin/qmk path (aka /home/{your-user}/.local/bin/qmk). Therefore, make sure that $HOME/.local/bin exists in your PATH env var. Check that’s applicable by simply running qmk -V for example. At the time of this writing (2022-07-18 23:20), version 1.1.0 should be reported.

QMK Setup

Before running it, make sure you don’t have (remove if it exists) the qmk_firmware folder in your home dir (use rm -rf ~/qmk_firmware just to be sure).
Run qmk setup GloriousThrall/qmk_firmware. Basically, we’re telling to CLI to use Glorious specific parts (not yet included in the official QMK repo).

$ qmk setup GloriousThrall/qmk_firmware
☒ Could not find qmk_firmware!
Would you like to clone GloriousThrall/qmk_firmware to /home/dxps/qmk_firmware? [y/n] y
Cloning into '/home/dxps/qmk_firmware'...
Updating files:  92% (31259/33900)
   ...
Submodule path 'lib/vusb': checked out 'bdb53e4c043d089279d9891b68bea77614cb97ee'
Ψ Successfully cloned https://github.com/GloriousThrall/qmk_firmware to /home/dxps/qmk_firmware!
Ψ Added https://github.com/qmk/qmk_firmware as remote upstream.
Ψ QMK Doctor is checking your environment.
Ψ CLI version: 1.1.0
Ψ QMK home: /home/dxps/qmk_firmware
Ψ Detected Linux.
Ψ Git branch: master
Ψ Repo version: 0.15.25
Ψ All dependencies are installed.
Ψ Found arm-none-eabi-gcc version 10.3.1
Ψ Found avr-gcc version 5.4.0
Ψ Found avrdude version 6.3-20171130
Ψ Found dfu-util version 0.9
Ψ Found dfu-programmer version 0.6.1
Ψ Submodules are up to date.
Ψ QMK is ready to go
$

And then:

$ cd qmk_firmware
$ git checkout glorious_gmmk2
$ make git-submodule

Verify Setup & Initial Build

Now it’s time to validate that this setup is fine by trying to build this QMK locally with the default keymap for the keyboard (again, GMMK 2 Compact in this case) using qmk compile -kb gmmk/gmmk2/p65/ansi -km default

$ qmk compile -kb gmmk/gmmk2/p65/ansi -km default
Ψ Compiling keymap with gmake --jobs=1 gmmk/gmmk2/p65/ansi:default

QMK Firmware 0.15.25
Making gmmk/gmmk2/p65/ansi with keymap default

arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
Copyright (C) 2020 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/gmmk/gmmk2/src/eeprom_flash.c                                                  [OK]
   ...
Compiling: lib/chibios-contrib/os/hal/src/hal_opamp.c                                               [OK]
Linking: .build/gmmk_gmmk2_p65_ansi_default.elf                                                     [OK]
Creating binary load file for flashing: .build/gmmk_gmmk2_p65_ansi_default.bin                      [OK]
Creating load file for flashing: .build/gmmk_gmmk2_p65_ansi_default.hex                             [OK]

Size after:
   text	   data	    bss	    dec	    hex	filename
      0	  43428	      0	  43428	   a9a4	gmmk_gmmk2_p65_ansi_default.bin

Copying gmmk_gmmk2_p65_ansi_default.bin to qmk_firmware folder                                      [OK]
(Firmware size check does not yet support WB32F3G71; skipping)
$ 

Cool! The compilation works fine. Next steps could be either just flashing this QMK firmware with default keymap, or first customize a bit the default keymap (which at the time of this writing has some wrong keys mapping in it).

Customizing the Keymap

As mentioned in the official guide, we can customize the keymap. As I wanted to use pretty much the same keys setup that I’m using in my other GMMK Pro keyboards, I had to do it. My OCD won’t let me live without it…

Opening keyboards/gmmk/gmmk2/p65/ansi/keymaps/default/keymap.c file (while still being in qmk_firmware folder, ofc), I updated as follows:

#include QMK_KEYBOARD_H

// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(
  KC_GESC,  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,  RGB_TOG,
  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_PGUP,
  MO(1),    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_PGDN,
  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_DEL,
  KC_LCTL,  KC_LGUI,  KC_LALT,                                KC_SPC,                                 KC_RALT,  MO(1),    KC_LEFT,  KC_DOWN,  KC_RGHT),

[1] = LAYOUT(
 KC_GRV,   KC_F1,    KC_F2,    KC_F3,    KC_F4,    KC_F5,    KC_F6,    KC_F7,    KC_F8,    KC_F9,    KC_F10,   KC_F11,   KC_F12,    _______,  RGB_MOD,
 _______,  _______,  _______,  KC_BSPC,  _______,  _______,  _______,  _______,  _______,  _______,  KC_CAPS,  RGB_HUD,  RGB_HUI,   _______,  RGB_VAI,
 _______,  KC_WREF,  _______,  KC_DEL,   RGB_SPD,  RGB_SPI,  KC_LEFT,  KC_DOWN,  KC_UP,    KC_RGHT,  KC_END,   _______,             RGB_VAD,
 _______,  _______,  KC_UNDO,  KC_CUT,   KC_COPY,  KC_PSTE,  RGB_VAD,  RGB_VAI,  KC_HOME,  KC_VOLD,  KC_VOLU,  KC_MUTE,  _______,   KC_PGUP,  KC_INS,
 _______,  _______,  _______,                                RESET,                                  _______,  _______,  KC_HOME,   KC_PGDN,  KC_END),

[2] = LAYOUT(
  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,   _______,  _______,
  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,   _______,  _______,
  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,             _______,
  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,  _______,   _______,  _______,
  _______,  _______,  _______,                                _______,                                _______,  _______,  _______,   _______,  _______)
};

Here are some notes to understand what’s all about it:

  1. Each key has a code (that’s why you see mainly the KC_ prefix).
    There are also some key codes for other functions, such as RGB lighting (those RGB_ values).
    The meaning of these codes can be found here.
  2. Layer 0 (the one that starts with [0] = LAYOUT() represents what keys are used by default.
    a. Here, for example, I moved the Delete key from top right near the arrows.
    That helps me to navigate using the arrows and quickly delete some character, if needed).
    Or, I’d use Fn with the arrows to have go Home, End, and Page Up, Page Down.
  3. Layer 1 (the one that starts with [1] = LAYOUT() represents what keys are used when Fn is pressed.

Some very important “shortcuts” to me are:

  1. Having Fn instead of Caps Lock.
    This is very handy (kinda influenced by HHKB approach).
  2. Using Fn plus (vi like options) i, j, k, l to navigate.
    Instead of having to go to the arrow keys, these “shortcuts” are easily reachable.
    I’m also using Fn + m for Home and Fn + ; for End.
    And with these, I really don’t have to reach the arrows keys.

I’m also using some other goodies like:

  • Fn + a for (browser) Refresh (see KC_WREF)
  • Fn + d for Delete (see KC_DEL)
  • Fn + e for Backspace (see KC_KC_BSPC)

Having this done, we have to recompile QMK again. Same as before, using qmk flash -kb gmmk/gmmk2/p65/ansi -km default.

If the compilation fails, most probably, you missed some comma (,) or have a typo in the codes (in this case, the compiler could give you some helpful hints).

Flashing the QMK Firmware

This phase includes some tricky parts. But I manage to get rid of them, so you can do it as well …

Update and Apply udev rules

In order to be able to access the (keyboard) device as a non-root user, some udev rules need to be applied. We have them already defined in qmk_firmware/util/udev/50-qmk.rules file. But there is no definition for this GMMK 2 Compact device.

Update this file by appending at the end of it the following line:

## GMMK 2 Compact
SUBSYSTEMS=="usb", ATTRS{idVendor}=="342d", ATTRS{idProduct}=="dfa0", TAG+="uaccess"

Then install and have them applied using:

  1. sudo cp qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d
  2. sudo udevadm control --reload-rules && sudo udevadm trigger

Without doing these, you’ll encounter errors like the following during flashing:
Cannot open DFU device 342d:dfa0 found on devnum 50 (LIBUSB_ERROR_ACCESS)

Install wb32-dfu-updater_cli

Next, there is one more thing to have (at least that was my experience). When trying to flash (as we’ll see in a minute), you might get an error about some wb32-dfu-updater_cli not found.
``

To have this utility available, do the followings:

  1. git clone https://github.com/WestberryTech/wb32-dfu-updater.git
  2. cd wb32-dfu-updater
  3. ./bootstrap.sh install
    I guess I was impatient at this time and I used sudo ./bootstrap.sh install.
    But I think it can be installed without sudo.

Put the Keyboard into Bootloader Mode

Before flashing the firmware, you have to put the keyboard in bootloader mode. Depending on which firmware you have, different shortcuts must be used before plugging it into your system.

If you have the Glorious Core firmware, use the Space + b shortcut.
If you have QMK firmware (a relevant case if later you’d like to update the keymap and apply it, or just switch back to Glorious’ firmware), use the Esc shortcut.

So, keep these keys pressed before and while connecting the keyboard.

Physically, when the keyboard starts in this mode no lights are on. But that’s not sufficient to me, so I generally watch the syslog using sudo tail -F /var/log/syslog.

There the confirmation exists:

$ sudo tail -F /var/log/syslog
   ...
Jul 18 21:32:48 codebox kernel: [1639145.833698] usb 1-4: new full-speed USB device number 50 using xhci_hcd
Jul 18 21:32:48 codebox kernel: [1639145.983140] usb 1-4: New USB device found, idVendor=342d, idProduct=dfa0, bcdDevice= 1.00
Jul 18 21:32:48 codebox kernel: [1639145.983153] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Jul 18 21:32:48 codebox kernel: [1639145.983158] usb 1-4: Product: WB Device in DFU Mode
Jul 18 21:32:48 codebox kernel: [1639145.983162] usb 1-4: Manufacturer: Westberry Tech.
Jul 18 21:32:48 codebox mtp-probe: checking bus 1, device 50: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4"
Jul 18 21:32:48 codebox mtp-probe: bus: 1, device: 50 was not an MTP device
Jul 18 21:32:48 codebox mtp-probe: checking bus 1, device 50: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4"
Jul 18 21:32:48 codebox mtp-probe: bus: 1, device: 50 was not an MTP device

Flash the QMK firmware

Finally, flash the previously compiled (recall that qmk compile -kb gmmk/gmmk2/p65/ansi -km default was used at that time and), this time using:
qmk flash -kb gmmk/gmmk2/p65/ansi -km default

Example:

$ qmk flash -kb gmmk/gmmk2/p65/ansi -km default  
Ψ Compiling keymap with gmake --jobs=1 gmmk/gmmk2/p65/ansi:default:flash

QMK Firmware 0.15.25
Making gmmk/gmmk2/p65/ansi with keymap default and target flash

arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
Copyright (C) 2020 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.

Size before:
   text	   data	    bss	    dec	    hex	filename
      0	  43428	      0	  43428	   a9a4	gmmk_gmmk2_p65_ansi_default.bin


Size after:
   text	   data	    bss	    dec	    hex	filename
      0	  43428	      0	  43428	   a9a4	gmmk_gmmk2_p65_ansi_default.bin

Copying gmmk_gmmk2_p65_ansi_default.bin to qmk_firmware folder                                      [OK]
----------------------------------------
.build/gmmk_gmmk2_p65_ansi_default.bin file opened
----------------------------------------
Found DFU
Opening DFU capable USB device ...
Device ID 342d:dfa0
----------------------------------------
The device bootloader version: 0.3
Chip id: 0x3A50A980
Flash size: 128 KBytes
Sram size: 28 KBytes
----------------------------------------
Start Download ...
Download block start address: 0x08000000
Download block size: 43428 Bytes
Writing ...
OK
Download completed!
$ 

Unplug the keyboard. Plug it back in and there you have it! QMK with a lot of freedom …

Pending Issues

I am pretty sure all of these will be solved, and none of them is major, imo.

  1. In the default (Glorious’) firmware, there is a nice RGB on/off toggle using Fn + z that turns on or off the keys and side lighting, both of them or just one of them.
    This is currently not possible - again, at the time of this writing - with RGB_TOG keycode. See before in the keymap that I’m setting this accessible by default (layer 0, without having to use Fn) on top right, instead of Delete key, that has a different position(s).

  2. “Shortcuts” for Undo, Cut, Copy, and Paste are currently not working.
    Based on what is documented, available also in QMK Configurator, and used in my other GMMK Pro cases (one such example), KC_UNDO, KC_CUT, KC_COPY, KC_PSTE key codes are not working as expected.
    The desire is to use Fn (CapsLock in this case) plus the standard z, x, c, v keys, instead of trying to reach to Ctrl key.

That’s quite a story, long, but hopefully helpful for this community and Glorious team itself to improve the official docs on the subject.

Take care and enjoy life and your keyboard(s)!

6 Likes

This is quite the breakdown! Thanks for opening the space for Linux users!

A Relevant Update (posted here since it seems that I can’t update the initial post).

Recently, I used ro8inmorgan’s qmk_firmware based on this reddit.

As it is also mentioned there, to use that version, in the QMK Setup step you just (the rest of steps remain the same) have to run:
qmk setup ro8inmorgan/qmk_firmware

What’s also very exciting to me is that he kindly help me having pretty much the best keymap (to my taste).

Now, keyboards/gmmk/gmmk2/p65/ansi/keymaps/default/keymap.c file looks like this:

#include QMK_KEYBOARD_H

// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(
KC_ESC,  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, RGB_TOG,
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_PGUP,
MO(1),   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_PGDN,
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_DEL,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1),  KC_LEFT, KC_DOWN, KC_RGHT),

[1] = LAYOUT(
KC_GRV,  KC_F1,      KC_F2,      KC_F3,      KC_F4,      KC_F5,    KC_F6,     KC_F7,    KC_F8,    KC_F9,    KC_F10,   KC_F11,   KC_F12,   RGB_SPI,  RGB_MOD,
_______, KC_VOLD,    KC_VOLU,    KC_BSPC,    LCTL(KC_W), _______,  _______,   _______,  KC_GRV,   _______,  KC_CAPS,  RGB_HUD,  RGB_HUI,  RGB_SPD,  RGB_VAI,
_______, KC_WREF,    LCTL(KC_S), KC_DEL,     LCTL(KC_F), _______,  KC_LEFT,   KC_DOWN,  KC_UP,    KC_RGHT,  KC_END,   _______,  _______,            RGB_VAD,
_______, LCTL(KC_Z), LCTL(KC_X), LCTL(KC_C), LCTL(KC_V), _______,  _______,   KC_HOME,  KC_VOLD,  KC_VOLU,  KC_MUTE,  _______,            KC_PGUP,  KC_INS,
_______, _______,    _______,                            _______,                                           _______,  _______,  KC_HOME,  KC_PGDN,  KC_END),

[2] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______)
};

The great parts on this updated keymap (besides the ones mentioned before in the previous keymap) are as follows:

  1. Fn (which is also CapsLock in this case) + z, x, c, v works as Undo, Cut, Copy, Paste.
    • It’s way easier to use this instead of the classic Ctrl + …
  2. Fn + i is for ` (backtick).
    • Of course, with Shift you get also the ~ (tilde).
    • Again, same idea: it’s easier to use CapsLock (as Fn) + i, instead of CapsLock + Esc.
  3. Fn + 2nd and 3rd key on the right side are now correctly controlling the brightness.
    • Previously, brightness down worked using Fn with Enter, instead of the key right to the Enter (PgDown in the default keymap and keycaps legends).
    • The 1st one (basically top right key) being used for turning on or off the lights.
      And with Fn and that key to choose the lighting mode (I simply like a static green color).
  4. Replaced KC_GESC with KC_ESC so that I can use Win + Esc (default) shortcut to lock (Linux Gnome) the screen.
  5. Have Fn + r as Ctrl+w
    • It’s a handy shortcut to close a browser tab or an app (depending on the app).
    • Although there are still available keys to use, I left Alt + F4 without an Fn related combo on purpose, as this has a bigger impact and I’d like to do that differently.
  6. Have Fn + s for Ctrl+s (save) and Fn + f for Ctrl+f (find), which may often be used.

I also removed the RESET from the Space key on layer 1 since if by mistake (quite easy to do that) Fn + Space, the keyboard became unresponsive and I had to reconnect it.
And I don’t think I’d need that. For putting it in bootloader mode (for any future QMK and/or keymap update), it works just by pressing Esc before and during the connect to the PC.

Hope it helps!

1 Like

Sure, glad to share and help! :blush:

1 Like

Thank you!
This lovely guide was really awesome as I would have spend some time trying to get everything to work without, especially that udev rule :slight_smile:

Those who want to use the graphical generator https://config.qmk.fm/
Make the config, download the json file, then use qmk json2c jour_config.json and put the output into the keyboards/gmmk/gmmk2/p65/ansi/keymaps/default/keymap.c file as described in the guide.

I found that the RGB_tog mode works for me, seems to be patched?
For Undo, Cut, Copy, and Paste one can use Mod Key combos, like LCTL(KC_C) or LCTL(KC_V) for copy and paste.

1 Like