QMK (Quantum Mechanical Keyboard) — программное обеспечение (прошивка) с открытым исходным кодом для клавиатур. Обладает широким функционалом: гибкая работа с раскладками, слои, макросы, подсветка, работа с внешними устройствами — подключение координатных устройств PS/2, звуковые эффекты и т. п. QMK работает на распространённых микроконтроллерах с архитектурой Atmel AVR и некоторых ARM.
Является форком TMK , развивается гораздо быстрее благодаря поддержке сообщества.
QMK — не единственный проект с исходным кодом для клавиатур, но его популярность значительно выше, чем у родительского проекта TMK и альтернативных проектов типа EasyAVR , PS2AVR или Kiibohd.
Уже есть проекты берущие QMK за основу:
− The VIA с графическим приложением-конфигуратором и редактированием на лету;
− VIAL как более универсальная и продвинутая версия VIA, из которой можно настроить tap dance;
− онлайн-конфигуратор remap-keys.app (!! да, как это как конфигуратор для ergodox-ez / moonlander – Oryx)
− прошивка на rust KeyToKey.
Также вдохновившись QMK/TMK сделали ZMK Firmware, ориентированную на беспроводные контроллеры (сейчас это практически безальтернативный выбор).
@optozorax ergodox ez layout
@optozorax moonlander layout
@stoneman’s Ergodox EZ layout
@Meagerfinding’s ErgoDox Layout
Miryoku layout
Подробное описание функционала QMK см. в оригинальной документации.
QMK используется в мелкосерийных и полностью самосборных клавиатурах. Со списком поддерживаемых клавиатур можно ознакомиться в Git-репозитории.
QMK может работать не только в качестве контроллера, т. е. устройства, непосредственно управляющего клавиатурной матрицей, но и конвертера — устройства, подключаемого к готовой клавиатуре с интерфейсами ADB, XT или даже USB. Всё верно, существует конвертер USB-USB, позволяющий добавить функционал QMK к любой USB-клавиатуре. Периодически появляется в продаже на 1upkeyboards.
Если вы планируете использовать QMK, то есть следующие варианты:
Основной архитектурой для QMK/TMK является AVR:
Некоторое время назад была добавлена поддержка ARM-микроконтроллеров, совместимых с ChibiOS. Наиболее распространённые и проверенные: Blue Pill, Black Pill, Teensy LC, Teensy 3.2. Поддержка ARM/ChibiOS развивается медленно, работает не весь функционал: Bootmagic, звук и т. д.
За подробностями стоит обратиться к оригинальной документации.
Обычно процесс прошивки клавиатуры состоит из трех шагов: подготовки и настройки файла раскладки под свои нужды и возможности клавиатуры или выбора готовой раскладки, компилирования прошивки под клавиатуру и, собственно, прошивки контроллера клавиатуры.
Для начала есть смысл воспользоваться Keyboard Layout Editor, чтобы облегчить подготовку раскладки перед прошивкой, или ознакомиться со свойствами готовых раскладок. Этот сайт позволяет очень хорошо визуализировать, как будет выглядеть раскладка на клавиатуре. Авторы раскладок часто снабжают свои варианты раскладок ссылками на этот сайт, где представлен их вариант.
Файл для прошивки можно создать двумя способами:
keymap.c, который вы пишете с нуля или правите готовый под свои нужды.У обоих способов есть свои плюсы и минусы. Онлайн-редактор не позволяет управлять довольно большим числом функций, он не поддерживает работу с макросами, не дает настраивать низкоуровневые параметры клавиатуры. Но очень прост и быстр в работе, достаточно раскидать нужные функции по кнопкам клавиатуры, и получить готовую прошивку. Создание кеймапов вручную открывает доступ ко всем возможностям, но требует хоть и небольшого, но уверенного понимания работы QMK.
Основная проблема для пользователей проекта в том, что онлайн редактор не работает с файлами keymap.c и не способен их экспортировать. Это заставляет пользователя проделывать двойную работу или сразу использовать ручное редактирование.
Данное руководство написано для начинающих (прим.: желательно иметь базовые представления о командных оболочках, принципах работы микроконтроллеров и минимальные навыки программирования), так что весь процесс, от установки QMK, драйверов до компиляции и прошивки будет описан для Windows.
Для начала нужна POSIX-среда, в качестве которой удобнее всего использовать Msys2. Устанавливаем, запускаем и получаем своеобразную unix оподобную среду с bash в качестве оболочки и Pacman в качестве менеджера пакетов. Исходники QMK размещены на Github, поэтому первым делом нужно будет установить клиент git:
pacman -S git
Затем качаем QMK:
git clone https://github.com/qmk/qmk_firmware
Переходим в каталог с QMK и запускаем скрипт, устанавливающий всё необходимое (компиляторы C для AVR и ARM, драйверы и т. д.):
cd qmk_firmware
./util/qmk_install.sh
Рассмотрим работу с прошивкой на примере простого макропада 9key, работающего на ATmega32U4 с матрицей 3×3.
В файле rules.mk определены некоторые константы для make: * MCU = atmega32u4 — тип микроконтроллера. * F_CPU = 16000000 — частота работы в Гц. ATmega32U4 встречаются на 16 МГц и на 8. * OPT_DEFS += -DBOOTLOADER_SIZE=4096 — размер загрузчика. В данной клавиатуре используется плата Pro Micro с загрузчиком Caterina, который имеет размер 4096 байт. * Build Options — в этой секции можно выключить ненужный функционал QMK, уменьшив размер прошивки и потребление памяти.
В config.h определены: конфигурация матрицы (в данном случае 3 ряда и 3 столбца), пины для строк и столбцов, подключение диодов (COL2ROW соответствует наиболее распространённому варианту с подключением диодов катодом в сторону строк), пин для подключения RGB-ленты WS1212. TAPPING_TERM 200 — значение таймаута для Tap Dance, функции, позволяющей назначить на одну клавишу несколько действий, зависящих от количества быстрых нажатий («тапов»).
В файле 9key.h, в макросе LAYOUT, определяется физическая раскладка клавиатуры — соответствие матрицы и физического расположения клавиш. В данном случае они совпадают:
#define LAYOUT( \
k00, k01, k02, \
k10, k11, k12, \
k20, k21, k22 \
) \
{ \
{ k00, k01, k02 }, \
{ k10, k11, k12 }, \
{ k20, k21, k22 } \
}
Допустим, что мы строим похожий макропад, но с более сложным расположением клавиш: клавиша, подключённая в матрице к третьему столбцу третьей строки (k22) физически будет находиться в левом верхнем углу, а средней клавиши в третьей строки не будет вообще. В этом случае матрица будет выглядеть вот так:
#define LAYOUT( \
k22, k01, k02, \
k10, k11, k12, \
k20, k00 \
) \
{ \
{ k00, k01, k02 }, \
{ k10, k11, k12 }, \
{ k20, KC_NO, k22 } \
}
Возможно, вы видели платы и монтажные пластины, поддерживающие несколько физических раскладок. Например, с возможностью установить левый Shift шириной 2,25U или вместо него поставить короткий левый Shift шириной 1,25U и дополнительную 1U-клавишу. Для таких случаев может быть определено несколько вариантов физической раскладки. Пример: плата GH60 Satan.
В каталоге keymaps лежат логические раскладки. Обычно там располагается каталог default с раскладной по умолчанию и дополнительные каталоги, в каждом из которых может лежать свой make-файл и файл keymap.c, в котором определяется самое интересное: слои, соответствие выдаваемых клавиатурой сканкодов и физической раскладки, макросы, логика работы светодиодов и прочий функционал. Можно будет создать свой вариант раскладки (например, в каталоге username) и компилировать прошивку с этой раскладкой командой make 9key:username.
Посмотрим, что происходит в стандартном файле keymap.c клавиатуры 9key:
#include QMK_KEYBOARD_H
// Tap Dance Declarations
enum {
ENT_5 = 0,
ZERO_7
};
// Macro Declarations
enum {
DBL_0 = 0
};
Определены имена для макросов Tap Dance и обычных.
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* LAYER 0
* ,-----------------------.
* | 1 | 2 | 3 |
* |-------+-------+-------|
* | 4 | 5/ENT | 6 | Dbl Tap 5 for Enter
* |-------+-------+-------|
* | 7/0 | 8 | 9/FN | 7/0 = Dbl Tap 7 for 0 - 9/FN = Hold 9 for FN
* `-----------------------'
*/
[0] = LAYOUT( \
KC_1, KC_2, KC_3, \
KC_4, TD(ENT_5), KC_6, \
TD(ZERO_7), KC_8, LT(1, KC_9) \
),
/* LAYER 1
* ,-----------------------.
* | ESC | + | - |
* |-------+-------+-------|
* | BSPC | * | / |
* |-------+-------+-------|
* | 00 | . | |
* `-----------------------'
*/
[1] = LAYOUT( \
KC_ESC, KC_PLUS, KC_MINS, \
KC_BSPC, KC_ASTR, KC_SLSH, \
M(DBL_0), KC_DOT, KC_TRNS \
)
};
qk_tap_dance_action_t tap_dance_actions[] = {
[ENT_5] = ACTION_TAP_DANCE_DOUBLE(KC_5, KC_ENT),
[ZERO_7] = ACTION_TAP_DANCE_DOUBLE(KC_7, KC_0)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
if (record->event.pressed) {
switch(id) {
case DBL_0:
SEND_STRING("00");
return false;
}
}
return MACRO_NONE;
};
void matrix_init_user(void) {
}
Определены логические раскладки для двух слоёв. В итоге получается некое подобие нампада. Так как клавиш у нас всего 9, то приходится применять смекалку:
qk_tap_dance_action_t tap_dance_actions[]: клавиша выдаёт «5» при одиночном нажатии и Enter при двойном.DBL_0. Действия для макросов перечислены в action_get_macro. В данном случае макрос выдаёт два нуля.KC_TRNS. Это специальный код для обозначения прозрачности. Подробное описание этой концепции можно посмотреть в документации.Проект TMK послужил основой для QMK. В настоящее время практически нет причин, по которым стоило бы использовать TMK вместо QMK. Исключение — некоторые конвертеры, не все из которых портировано в QMK.