QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however.
There are two main types of configuration files in QMK- config.h
and rules.mk
. These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:
Every available setting in QMK has a default. If that setting is not set at the Keyboard, Folder, or Keymap level this is the setting that will be used.
This level contains config options that should apply to the whole keyboard. Some settings won't change in revisions, or most keymaps. Other settings are merely defaults for this keyboard and can be overridden by folders and/or keymaps.
Some keyboards have folders and sub-folders to allow for different hardware configurations. Most keyboards only go 1 folder deep, but QMK supports structures up to 5 folders deep. Each folder can have its own config.h
and rules.mk
files that are incorporated into the final configuration.
This level contains all of the options for that particular keymap. If you wish to override a previous declaration, you can use #undef <variable>
to undefine it, where you can then redefine it without an error.
config.h
FileThis is a C header file that is one of the first things included, and will persist over the whole project (if included). Lots of variables can be set here and accessed elsewhere. The config.h
file shouldn't be including other config.h
files, or anything besides this:
#include "config_common.h"
#define VENDOR_ID 0x1234
#define PRODUCT_ID 0x5678
#define DEVICE_VER 0
#define MANUFACTURER Me
#define PRODUCT Board
#define DESCRIPTION a keyboard
#define MATRIX_ROWS 5
#define MATRIX_COLS 15
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }
#define MATRIX_HAS_GHOST
#define DIODE_DIRECTION COL2ROW
#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
#define AUDIO_VOICES
#define C4_AUDIO
#define C5_AUDIO
#define C6_AUDIO
#define B5_AUDIO
#define B6_AUDIO
#define B7_AUDIO
#define BACKLIGHT_PIN B7
#define BACKLIGHT_LEVELS 3
#define BACKLIGHT_BREATHING
#define BREATHING_PERIOD 6
#define DEBOUNCE 5
#define LOCKING_SUPPORT_ENABLE
#define LOCKING_RESYNC_ENABLE
#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
#define USB_MAX_POWER_CONSUMPTION 500
#define USB_POLLING_INTERVAL_MS 10
#define F_SCL 100000L
400000L
, except for keyboards using split_common
, where the default is 100000L
.If you define these options you will disable the associated feature, which can save on code size.
#define NO_DEBUG
#define NO_PRINT
#define NO_ACTION_LAYER
#define NO_ACTION_TAPPING
#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
If you define these options you will enable the associated feature, which may increase your code size.
#define FORCE_NKRO
#define STRICT_LAYER_RELEASE
#define TAPPING_TERM 200
#define TAPPING_TERM_PER_KEY
TAPPING_TERM
settings#define RETRO_TAPPING
#define TAPPING_TOGGLE 2
#define PERMISSIVE_HOLD
TAPPING_TERM
#define IGNORE_MOD_TAP_INTERRUPT
TAPPING_TERM
for both keys.#define TAPPING_FORCE_HOLD
TT
or the One Shot Tap Toggle)#define LEADER_TIMEOUT 300
LEADER_PER_KEY_TIMING
option, which resets the timeout after each key is tapped.#define LEADER_PER_KEY_TIMING
#define LEADER_KEY_STRICT_KEY_PROCESSING
MT(MOD_CTL, KC_A)
if you want to use KC_A
.#define ONESHOT_TIMEOUT 300
#define ONESHOT_TAP_TOGGLE 2
#define QMK_KEYS_PER_SCAN 4
process_record()
per scan. This has little impact on most typing, but
if you're doing a lot of chords, or your scan rate is slow to begin with, you can
have some delay in processing key events. Each press and release is a separate
event. For a keyboard with 1ms or so scan times, even a very fast typist isn't
going to produce the 500 keystrokes a second needed to actually get more than a
few ms of delay from this. But if you're doing chording on something with 3-4ms
scan times? You probably want this.#define COMBO_COUNT 2
#define COMBO_TERM 200
TAPPING_TERM
if not defined.#define TAP_CODE_DELAY 100
register_code
and unregister_code
, if you're having issues with it registering properly (common on VUSB boards). The value is in milliseconds.#define TAP_HOLD_CAPS_DELAY 80
LT
, MT
) when using KC_CAPSLOCK
keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher.#define RGB_DI_PIN D7
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12
#define RGBLIGHT_SPLIT
#define RGBLED_SPLIT { 6, 6 }
RGB_DI_PIN
on each half of a split keyboard#define RGBLIGHT_HUE_STEP 12
#define RGBLIGHT_SAT_STEP 25
#define RGBLIGHT_VAL_STEP 12
#define RGBW_BB_TWI
#define MOUSEKEY_INTERVAL 20
#define MOUSEKEY_DELAY 0
#define MOUSEKEY_TIME_TO_MAX 60
#define MOUSEKEY_MAX_SPEED 7
#define MOUSEKEY_WHEEL_DELAY 0
Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk
SPLIT_TRANSPORT = custom
One thing to remember, the side that the USB port is plugged into is always the master half. The side not plugged into USB is the slave.
There are a few different ways to set handedness for split keyboards (listed in order of precedence):
SPLIT_HAND_PIN
: Reads a pin to determine handedness. If pin is high, it's the left side, if low, the half is determined to be the right sideEE_HANDS
and flash eeprom-lefthand.eep
/eeprom-righthand.eep
to each half
:dfu-split-left
/:dfu-split-right
to flash these EEPROM files:avrdude-split-left
/:avrdude-split-right
:dfu-util-split-left
/:dfu-util-split-right
MASTER_RIGHT
: Half that is plugged into the USB port is determined to be the master and right half (inverse of the default)#define SPLIT_HAND_PIN B7
B7
with the pin you are using. This is optional, and if you leave SPLIT_HAND_PIN
undefined, then you can still use the EE_HANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses.#define EE_HANDS
(only works if SPLIT_HAND_PIN
is not defined)
eeprom-lefthand.eep
/eeprom-righthand.eep
has been flashed to their respective halves.#define MASTER_RIGHT
#define USE_I2C
#define SOFT_SERIAL_PIN D0
D0
or D1
,D2
,D3
,E6
.#define MATRIX_ROW_PINS_RIGHT { <row pins> }
#define MATRIX_COL_PINS_RIGHT { <col pins> }
MATRIX_ROW_PINS_RIGHT
/MATRIX_COL_PINS_RIGHT
. Currently, the size of MATRIX_ROW_PINS
must be the same as MATRIX_ROW_PINS_RIGHT
and likewise for the definition of columns.#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
DIRECT_PINS_RIGHT
. Currently, the size of DIRECT_PINS
must be the same as DIRECT_PINS_RIGHT
.#define RGBLED_SPLIT { 6, 6 }
#define SELECT_SOFT_SERIAL_SPEED <speed>
(default speed is 1)
#define SPLIT_USB_DETECT
#define SPLIT_USB_TIMEOUT 2500
SPLIT_USB_DETECT
rules.mk
FileThis is a make file that is included by the top-level Makefile
. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features.
DEFAULT_FOLDER
FIRMWARE_FORMAT
qmk_firmware
folder after building.SRC
LAYOUTS
MCU = atmega32u4
F_CPU = 16000000
ARCH = AVR8
F_USB = $(F_CPU)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
BOOTLOADER = atmel-dfu
with the following options:
atmel-dfu
lufa-dfu
qmk-dfu
halfkay
caterina
bootloadHID
USBasp
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
BOOTMAGIC_ENABLE
MOUSEKEY_ENABLE
EXTRAKEY_ENABLE
CONSOLE_ENABLE
COMMAND_ENABLE
COMBO_ENABLE
NKRO_ENABLE
AUDIO_ENABLE
RGBLIGHT_ENABLE
LEADER_ENABLE
MIDI_ENABLE
UNICODE_ENABLE
BLUETOOTH_ENABLE
BLUETOOTH
SPLIT_KEYBOARD
CUSTOM_MATRIX
DEBOUNCE_TYPE
WAIT_FOR_USB
NO_USB_STARTUP_CHECK
LINK_TIME_OPTIMIZATION_ENABLE
= Enables Link Time Optimization (LTO
) when compiling the keyboard. This makes the process take longer, but can significantly reduce the compiled size (and since the firmware is small, the added time is not noticable). However, this will automatically disable the old Macros and Functions features automatically, as these break when LTO
is enabled. It does this by automatically defining NO_ACTION_MACRO
and NO_ACTION_FUNCTION
In order to provide services over USB, QMK has to use USB endpoints. These are a finite resource: each microcontroller has only a certain number. This limits what features can be enabled together. If the available endpoints are exceeded, a build error is thrown.
The following features can require separate endpoints:
MOUSEKEY_ENABLE
EXTRAKEY_ENABLE
CONSOLE_ENABLE
NKRO_ENABLE
MIDI_ENABLE
RAW_ENABLE
VIRTSER_ENABLE
In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint.
By default, MOUSEKEY
, EXTRAKEY
, and NKRO
are combined into a single endpoint.
The base keyboard functionality can also be combined into the endpoint,
by setting KEYBOARD_SHARED_EP = yes
.
This frees up one more endpoint,
but it can prevent the keyboard working in some BIOSes,
as they do not implement Boot Keyboard protocol switching.
Combining the mouse also breaks Boot Mouse compatibility.
The mouse can be uncombined by setting MOUSE_SHARED_EP = no
if this functionality is required.