import { _ as _export_sfc, c as createElementBlock, o as openBlock, a8 as createStaticVNode } from "./chunks/framework.B9AX-CPi.js"; const __pageData = JSON.parse('{"title":"Configuring QMK","description":"","frontmatter":{},"headers":[],"relativePath":"config_options.md","filePath":"config_options.md","lastUpdated":null}'); const _sfc_main = { name: "config_options.md" }; const _hoisted_1 = /* @__PURE__ */ createStaticVNode('
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 three main types of configuration files in QMK:
config.h
, which contains various preprocessor directives (#define
, #ifdef
)rules.mk
, which contains additional variablesinfo.json
, which is utilized for data-driven configurationThis page will only discuss the first two types, config.h
and rules.mk
.
TIP
While not all settings have data-driven equivalents yet, keyboard makers are encouraged to utilize the info.json
file to set the metadata for their boards when possible. See the info.json
Format page for more details.
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
File This 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.
#define VENDOR_ID 0x1234
#define PRODUCT_ID 0x5678
#define DEVICE_VER 0x0100
#define MANUFACTURER "Me"
#define PRODUCT "Board"
#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 MATRIX_IO_DELAY 30
#define MATRIX_HAS_GHOST
#define MATRIX_UNSELECT_DRIVE_HIGH
#define DIODE_DIRECTION COL2ROW
#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
#define AUDIO_VOICES
#define C4_AUDIO
#define AUDIO_PIN C4
#define C5_AUDIO
#define AUDIO_PIN C5
#define C6_AUDIO
#define AUDIO_PIN C6
#define B5_AUDIO
#define AUDIO_PIN B5
, or use #define AUDIO_PIN_ALT B5
if a C
pin is enabled with AUDIO_PIN
#define B6_AUDIO
#define AUDIO_PIN B6
, or use #define AUDIO_PIN_ALT B6
if a C
pin is enabled with AUDIO_PIN
#define B7_AUDIO
#define AUDIO_PIN B7
, or use #define AUDIO_PIN_ALT B7
if a C
pin is enabled with AUDIO_PIN
#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 USB_SUSPEND_WAKEUP_DELAY 0
#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
If you define these options you will enable the associated feature, which may increase your code size.
#define ENABLE_COMPILE_KEYCODE
QK_MAKE
keycode#define FORCE_NKRO
#define STRICT_LAYER_RELEASE
#define TAPPING_TERM 200
#define TAPPING_TERM_PER_KEY
TAPPING_TERM
settings#define RETRO_TAPPING
TAPPING_TERM
, if there was no other key interruption between press and release#define RETRO_TAPPING_PER_KEY
RETRO_TAPPING
settings#define TAPPING_TOGGLE 2
#define PERMISSIVE_HOLD
TAPPING_TERM
#define PERMISSIVE_HOLD_PER_KEY
PERMISSIVE_HOLD
settings#define QUICK_TAP_TERM 100
TT
or the One Shot Tap Toggle)TAPPING_TERM
if not defined#define QUICK_TAP_TERM_PER_KEY
QUICK_TAP_TERM
settings#define HOLD_ON_OTHER_KEY_PRESS
#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
HOLD_ON_OTHER_KEY_PRESS
settings#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 MOUSE_EXTENDED_REPORT
#define ONESHOT_TIMEOUT 300
#define ONESHOT_TAP_TOGGLE 2
#define COMBO_TERM 200
TAPPING_TERM
if not defined.#define COMBO_MUST_HOLD_MODS
#define COMBO_MOD_TERM 200
#define COMBO_MUST_HOLD_PER_COMBO
get_combo_must_hold()
function#define COMBO_TERM_PER_COMBO
get_combo_term()
function#define COMBO_STRICT_TIMER
#define COMBO_NO_TIMER
#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 and defaults to 0
.#define TAP_HOLD_CAPS_DELAY 80
LT
, MT
) when using KC_CAPS_LOCK
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 KEY_OVERRIDE_REPEAT_DELAY 500
#define LEGACY_MAGIC_HANDLING
#define WS2812_DI_PIN D7
#define RGBLIGHT_LAYERS
#define RGBLIGHT_MAX_LAYERS
#define RGBLIGHT_LAYER_BLINK
#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF
#define RGBLIGHT_LED_COUNT 12
#define RGBLIGHT_SPLIT
#define RGBLED_SPLIT { 6, 6 }
#define RGBLIGHT_HUE_STEP 12
#define RGBLIGHT_SAT_STEP 25
#define RGBLIGHT_VAL_STEP 12
#define WS2812_RGBW
#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 SPLIT_HAND_MATRIX_GRID <out_pin>,<in_pin>
#define SPLIT_HAND_MATRIX_GRID_LOW_IS_LEFT
, it is determined to be left when the level is low.#define EE_HANDS
(only works if SPLIT_HAND_PIN
and SPLIT_HAND_MATRIX_GRID
are 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 2000
SPLIT_USB_DETECT
#define SPLIT_USB_TIMEOUT_POLL 10
SPLIT_USB_DETECT
#define SPLIT_WATCHDOG_ENABLE
SPLIT_USB_DETECT
#define SPLIT_WATCHDOG_TIMEOUT 3000
SPLIT_WATCHDOG_ENABLE
#define FORCED_SYNC_THROTTLE_MS 100
#define SPLIT_TRANSPORT_MIRROR
#define SPLIT_LAYER_STATE_ENABLE
#define SPLIT_LED_STATE_ENABLE
#define SPLIT_MODS_ENABLE
#define SPLIT_WPM_ENABLE
#define SPLIT_OLED_ENABLE
#define SPLIT_ST7565_ENABLE
#define SPLIT_TRANSACTION_IDS_KB .....
#define SPLIT_TRANSACTION_IDS_USER .....
rules.mk
File This 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
LIB_SRC
LIB_SRC
is linked after the files specified by SRC
. For example, if you specify:SRC += a.c\nLIB_SRC += lib_b.c\nSRC += c.c\nLIB_SRC += lib_d.c
... a.o c.o ... lib_b.a lib_d.a ...
LAYOUTS
LTO_ENABLE
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
usbasploader
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.
MAGIC_ENABLE
BOOTMAGIC_ENABLE
MOUSEKEY_ENABLE
EXTRAKEY_ENABLE
CONSOLE_ENABLE
COMMAND_ENABLE
COMBO_ENABLE
NKRO_ENABLE
RING_BUFFERED_6KRO_REPORT_ENABLE
AUDIO_ENABLE
KEY_OVERRIDE_ENABLE
RGBLIGHT_ENABLE
LEADER_ENABLE
MIDI_ENABLE
UNICODE_ENABLE
BLUETOOTH_ENABLE
SPLIT_KEYBOARD
CUSTOM_MATRIX
DEBOUNCE_TYPE
USB_WAIT_FOR_ENUMERATION
NO_USB_STARTUP_CHECK
DEFERRED_EXEC_ENABLE
DYNAMIC_TAPPING_TERM_ENABLE
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.