Ремонт глючной клавиатуры прошивкой QMK на STM32F103

Здравствуйте, SE7ENовчане! Я зарегистрировался, чтобы поделиться опытом восстановления работоспособности механической клавиатуры Royal Kludge R87 Pro.

Первая попытка отняла много времени: я применил аналог CH32F103 вместо STM32F103R8T6, по ошибке заказывал контроллеры с 48 выводами, а также столкнулся с тем, что некоторые чипы не запускались с 12 MHz кварцем. В качестве основы послужил материал по ссылке, но здесь я опишу детали, которые нигде раньше не упоминались.

Для решения технических задач я не раз прибегал к помощи AI, однако в этой статье представлены лишь этапы работы и итоговый результат.

Начало

Итак, перед нами Royal Kludge R87 Pro:

Ремонт глючной клавиатуры прошивкой QMK на STM32F103
Вид с обратной стороны свитчей

При нажатии «1» вместо него выводились «1 2 3 4 5», при «Q» — «Q W E R T» и т. д. Разбор показал, что на плате стоит микроконтроллер WB32FQ95RCT6 — китайская модель с минимальной поддержкой. Прозвонка матрицы тестером выявила, что сбой происходит на выводах контроллера (диодов и резисторов в цепи нет), поэтому я выбрал STM32F103R8T6 (ARM Cortex-M3, 72 MHz, 64 KB Flash, LQFP-64).

Ранее я пробовал прикладной вариант на RP2040zero, но отказался от «колхоза»: проще заменить сам контроллер на плате, к которой уже ведут все нужные дорожки. Старый чип выпаял феном, а STM32F103 впаял паяльником с припоем Rose 92–95 °C и оплеткой для удаления излишков олова.

Чтобы не задействовать 100+ выводов, клавиши в большинстве механических клавиатур объединены в матрицу: строки и столбцы. У R87 Pro шесть строк (нумерация 0…5) и 17 столбцов (0…16). Для каждой я нашёл официальную схему, но сверял контакты тестером — один энкодер оказался вне документации. Затем зарисовал матрицу вручную и прозвонил всё до выводов STM32F103.

распечатанная матрица с пометками
Распечатанная схема матрицы с моими пометками (синей ручкой — строки/столбцы, красной — выводы МК)

В итоге каждая из 6 строк и 17 столбцов подключена к 23 выводам контроллера. Параметры матрицы и физическое расположение клавиш (x,y) занёс в keyboard.json, взяв за основу конфигурацию moky88 (98% совпадения) и разделив диапазон координат 0,0…224,64 пропорционально размерам R87 Pro.

файл keyboard.json
Пример файла keyboard.json

Прошивка

Для сборки прошивки в каталоге клавиатуры должны присутствовать стандартные файлы QMK:

структура keymaps/default
В папке keymaps/default — только keymap.c

Ниже — выдержки из моих конфигурационных файлов для STM32F103.

config.h
#pragma once
#define F_CPU 72000000
#define MATRIX_ROWS 6
#define MATRIX_COLS 17
#define DEBOUNCE 5

undef ENCODER_A_PINS

undef ENCODER_B_PINS

define ENCODER_MAP_ENABLE

define ENCODER_A_PINS { B6 }

define ENCODER_B_PINS { B7 }

define ENCODER_RESOLUTION 4

define LED_CAPS_LOCK_PIN A9

define USB_POLLING_INTERVAL_MS 1

define WS2812_DRIVER SPI

define WS2812_DI_PIN A7

define DRIVER_LED_TOTAL 121

define RGB_MATRIX_LED_COUNT 121

define ENABLE_RGB_MATRIX_BREATHING

... (24 эффекта RGB Matrix)

define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_ALL

define RGB_MATRIX_DEFAULT_HUE 0

define RGB_MATRIX_DEFAULT_SAT 255

define RGB_MATRIX_DEFAULT_VAL 150

define RGB_MATRIX_DEFAULT_SPD 127

</div>
halfconf.h
#pragma once
#undef HAL_USE_SPI
#define HAL_USE_SPI TRUE
#include_next "halconf.h"
mcuconf.h
#pragma once
#include_next "mcuconf.h"
#undef STM32_HSECLK
#define STM32_HSECLK 8000000U
#undef STM32_PLLMUL_VALUE
#define STM32_PLLMUL_VALUE 9
#undef STM32_USB_USE_USB1
#define STM32_USB_USE_USB1 TRUE
#define STM32_OTG1_IRQ_PRIORITY 6
#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE
rules.mk
MCU = STM32F103
BOARD = STM32_F103_STM32DUINO
BOOTLOADER = custom
PLATFORM = chibios

USE_USB = yes USE_FPU = no LTO_ENABLE = yes

EXTRAKEY_ENABLE = yes RGB_MATRIX_ENABLE = yes RGB_MATRIX_DRIVER = ws2812 ENCODER_ENABLE = yes CONSOLE_ENABLE = no COMMAND_ENABLE = no

keymap.c
#include QMK_KEYBOARD_H

led_config_t g_led_config = { { / Key Matrix to LED Index / ... }, { / LED Index to Physical Position / ... }, { / LED Index to Flag / ... } };

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT( KC_ESC, KC_F1, ... KC_RGHT ), [1] = LAYOUT( ___, KC_MYCM, ... RM_SPDU ) };

// Энкодер const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = { [0] = { {KC_VOLU, KC_VOLD} }, [1] = { {RM_NEXT, RM_PREV} } };

// Индикатор Caps Lock void keyboard_post_init_user(void) { palSetLineMode(A9, PAL_MODE_OUTPUT_PUSHPULL); writePinHigh(A9); palSetLineMode(B8, PAL_MODE_OUTPUT_PUSHPULL); writePinHigh(B8); }

void led_set_user(uint8_t usb_led) { bool caps = usb_led & (1 << 0); if (caps) writePinLow(A9); else writePinHigh(A9); }

bool gu_enabled = true;

bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case GU_TOGG: if (record->event.pressed) { keymap_config.no_gui = !keymap_config.no_gui; if (keymap_config.no_gui) writePinHigh(B8); else writePinLow(B8); } return false; } return true; }

Прошивал контроллер программатором ST-Link V2 (подключив +3.3 V, SWDIO, SWCLK, GND), используя STM32CubeProgrammer. После заливки загрузчика generic_boot20_pc13.bin и собранной прошивки Windows наконец увидела устройство и все клавиши ожили.

Подсветка

Клавиатура оснащена адресными светодиодами WS2812 (питание +3.3 V, GND, DATA+ и DATA–). Они передают код по «цепочке змейкой»: первый светодиод принимает данные и отсылает их дальше. Тестером определил вывод контроллера для DATA+, затем занумеровал 88 LED под клавишами, по 14 слева и справа, и 5 возле индикаторов. Всего 121 LED.

нумерация светодиодов
«Пробел» на фотографии — LED #1, но в QMK он должен быть № 0

Нумерацию и физические координаты прописал в keymap.c, сохранив NO_LED для пустых ячеек матрицы. В rules.mk добавил:

RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = ws2812

Список 24 эффектов RGB Matrix можно выбрать из официальной документации:

список эффектов подсветки
Перечень использованных эффектов подсветки

После включения подсветки при нажатиях на столбец с F9 стали срабатывать «параллельные» клавиши. Чтобы устранить помехи, перепаял линию DATA+ с PB15 на PA7, отпаяв старую дорожку и подведя тонкий провод от нового вывода к резистору 390 Ω.

перепайка подсветки
Красным — провод от PA7 к резистору 390 Ω, жёлтым — отрезанная дорожка PB15

После этой правки все сбои исчезли. Осталось настроить слои через FN, интегрировать энкодер и индикатор Caps Lock, а также активировать мультимедийные клавиши.

Финал

Работа над энкодером заняла дополнительное время: для регулировки громкости потребовалась опция EXTRAKEY_ENABLE = yes в rules.mk. Кнопка нажатия энкодера оказалась подключена к матричным координатам [3, 14], а не [0, 16] — это пришлось учесть в keyboard.json. Индикатор Caps Lock запустился после правильной конфигурации вывода A9.

В итоге клавиатура обрела «вторую жизнь»: все кнопки функционируют, RGB Matrix работает в 24 режимах, энкодер регулирует громкость и переключает режимы подсветки, индикатор Caps Lock зажигается и гаснет. В будущем имеет смысл применить контроллер STM32 с встроенным загрузчиком для удобного входа в режим прошивки.

итоговый вид клавиатуры
Готовый результат: полностью восстановленная Royal Kludge R87 Pro

P.S. В целом R87 Pro не оправдывает своей стоимости: свитчи тихие и сменные, но непрозрачные, а кейкапы не пропускают свет.

 

Источник

Читайте также