Compare commits

...

13 Commits

Author SHA1 Message Date
Nick Brassel dccada95aa Remove debugging prints. (#24271) 2024-08-12 23:25:29 +10:00
Nick Brassel 380e0c9cad Userspace: add support for adding environment variables during build (#22887) 2024-08-12 22:34:22 +10:00
Nick Brassel 158aaef78c ChibiOS update script updates. (#24267) 2024-08-12 20:35:56 +10:00
Andrew Kannan 5acc3b2b7b Add extra compatibility to Sat75 HS PCB (#24156) 2024-08-07 14:40:31 -06:00
stephen776 78900720fd JJ50 v2 Support (#24212)
* add support for JJ50 V2 PCB

* fix bootloader config

* update mousekey setting

* run format-json

---------

Co-authored-by: Steve Jacobs <sjacobs@truefit.io>
2024-08-07 14:34:21 -06:00
Sắn c67c3d375b Add support for bunnygirl65 (#24244)
* Add support for bunnygirl65

* Update keyboard.json

* Update keymap.c

* Update keymap.c

* Update keyboards/sawnsprojects/bunnygirl65/readme.md

Co-authored-by: Joel Challis <git@zvecr.com>

* Update keyboards/sawnsprojects/bunnygirl65/keyboard.json

Co-authored-by: Joel Challis <git@zvecr.com>

* Update keyboards/sawnsprojects/bunnygirl65/keyboard.json

---------

Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <jack@pngu.org>
2024-08-07 14:28:41 -06:00
eason 75402109e9 Add Void65h (#24183) 2024-08-04 00:46:12 +01:00
Ryan fa657fef70 atlantis/ak81_ve: move RGB Matrix LED config to data driven (#24115) 2024-08-04 00:38:26 +01:00
Ryan eb78ca1c1a handwired/p65rgb: move RGB Matrix LED config to data driven (#24124) 2024-08-04 00:37:57 +01:00
Christian Greene d28a50e176 FX19 Support (#24220) 2024-08-03 23:11:49 +01:00
akyp c7662e4f36 [Keyboard] Add archerkeyboard/desire65 (#23776)
Co-authored-by: jack <0x6a73@protonmail.com>
2024-07-31 10:07:51 +10:00
Cipulot 73cb6fd89f cipulot/ec_60x: Fix VIA layout options (#24217)
This fixes the issue of one layout option not being applied correctly because it was out of bound.
2024-07-30 22:21:42 +01:00
Dasky d538451adb Remove AVR GCC version warning (#24206) 2024-07-28 19:16:15 +01:00
50 changed files with 1679 additions and 257 deletions
+8 -5
View File
@@ -34,10 +34,13 @@ ifeq ($(strip $(DUMP_CI_METADATA)),yes)
endif
# Force expansion
TARGET := $(TARGET)
override TARGET := $(TARGET)
ifneq ($(FORCE_LAYOUT),)
TARGET := $(TARGET)_$(FORCE_LAYOUT)
override TARGET := $(TARGET)_$(FORCE_LAYOUT)
endif
ifneq ($(CONVERT_TO),)
override TARGET := $(TARGET)_$(CONVERT_TO)
endif
# Object files and generated keymap directory
@@ -58,9 +61,6 @@ ifdef SKIP_GIT
VERSION_H_FLAGS += --skip-git
endif
# Generate the board's version.h file.
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
# Determine which subfolders exist.
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
@@ -218,6 +218,9 @@ endif
include $(BUILDDEFS_PATH)/converters.mk
# Generate the board's version.h file.
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
MCU_ORIG := $(MCU)
include $(wildcard $(PLATFORM_PATH)/*/mcu_selection.mk)
-3
View File
@@ -32,9 +32,6 @@ ifneq ($(CONVERT_TO),)
PLATFORM_KEY = $(shell echo $(CONVERTER) | cut -d "/" -f2)
# force setting as value can be from environment
override TARGET := $(TARGET)_$(CONVERT_TO)
# Configure any defaults
OPT_DEFS += -DCONVERT_TO_$(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]')
OPT_DEFS += -DCONVERTER_TARGET=\"$(CONVERT_TO)\"
+17 -6
View File
@@ -16,12 +16,6 @@
"type": "object",
"additionalProperties": {"type": "boolean"}
},
"build_target": {
"oneOf": [
{"$ref": "#/keyboard_keymap_tuple"},
{"$ref": "#/json_file_path"}
]
},
"filename": {
"type": "string",
"minLength": 1,
@@ -53,6 +47,19 @@
{"$ref": "#/keyboard"},
{"$ref": "#/filename"}
],
"minItems": 2,
"maxItems": 2,
"unevaluatedItems": false
},
"keyboard_keymap_env": {
"type": "array",
"prefixItems": [
{"$ref": "#/keyboard"},
{"$ref": "#/filename"},
{"$ref": "#/kvp_object"}
],
"minItems": 3,
"maxItems": 3,
"unevaluatedItems": false
},
"keycode": {
@@ -87,6 +94,10 @@
"maxLength": 7,
"pattern": "^[A-Z][A-Zs_0-9]*$"
},
"kvp_object": {
"type": "object",
"additionalProperties": {"type": "string"}
},
"layout_macro": {
"oneOf": [
{
+9 -1
View File
@@ -3,6 +3,14 @@
"$id": "qmk.user_repo.v1",
"title": "User Repository Information",
"type": "object",
"definitions": {
"build_target": {
"oneOf": [
{"$ref": "qmk.definitions.v1#/keyboard_keymap_tuple"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
},
},
"required": [
"userspace_version",
"build_targets"
@@ -15,7 +23,7 @@
"build_targets": {
"type": "array",
"items": {
"$ref": "qmk.definitions.v1#/build_target"
"$ref": "#/definitions/build_target"
}
}
}
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.user_repo.v1_1",
"title": "User Repository Information",
"type": "object",
"definitions": {
"build_target": {
"oneOf": [
{"$ref": "qmk.definitions.v1#/keyboard_keymap_tuple"},
{"$ref": "qmk.definitions.v1#/keyboard_keymap_env"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
},
},
"required": [
"userspace_version",
"build_targets"
],
"properties": {
"userspace_version": {
"type": "string",
"enum": ["1.1"]
},
"build_targets": {
"type": "array",
"items": {
"$ref": "#/definitions/build_target"
}
}
}
}
@@ -0,0 +1,192 @@
{
"manufacturer": "archerkeyboard",
"keyboard_name": "desire65",
"maintainer": "akyp",
"bootloader": "rp2040",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"extrakey": true,
"mousekey": true,
"nkro": true,
"rgblight": true
},
"indicators": {
"caps_lock": "GP18"
},
"matrix_pins": {
"cols": ["GP21", "GP29", "GP1", "GP0", "GP15", "GP14", "GP13", "GP12", "GP11", "GP10", "GP9", "GP8", "GP2", "GP5", "GP4", "GP3"],
"rows": ["GP24", "GP25", "GP19", "GP16", "GP17"]
},
"processor": "RP2040",
"rgblight": {
"animations": {
"breathing": true,
"rainbow_mood": true,
"rainbow_swirl": true,
"static_gradient": true,
"twinkle": true
},
"default": {
"animation": "rainbow_mood",
"val": 128
},
"driver": "ws2812",
"led_count": 17,
"sleep": true
},
"url": "https://archerkeyboard.com",
"usb": {
"device_version": "0.0.1",
"pid": "0x0002",
"vid": "0x0361"
},
"ws2812": {
"driver": "vendor",
"pin": "GP26"
},
"community_layouts": ["65_ansi_blocker_tsangan", "65_ansi_blocker_tsangan_split_bs"],
"layouts": {
"LAYOUT_65_ansi_blocker_tsangan": {
"layout": [
{"label": "Esc", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "!", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "@", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "#", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "$", "matrix": [0, 4], "x": 4, "y": 0},
{"label": "%", "matrix": [0, 5], "x": 5, "y": 0},
{"label": "^", "matrix": [0, 6], "x": 6, "y": 0},
{"label": "&", "matrix": [0, 7], "x": 7, "y": 0},
{"label": "*", "matrix": [0, 8], "x": 8, "y": 0},
{"label": "(", "matrix": [0, 9], "x": 9, "y": 0},
{"label": ")", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "_", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "+", "matrix": [0, 12], "x": 12, "y": 0},
{"label": "Backspace", "matrix": [0, 14], "x": 13, "y": 0, "w": 2},
{"label": "Home", "matrix": [0, 15], "x": 15, "y": 0},
{"label": "Tab", "matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"label": "Q", "matrix": [1, 2], "x": 1.5, "y": 1},
{"label": "W", "matrix": [1, 3], "x": 2.5, "y": 1},
{"label": "E", "matrix": [1, 4], "x": 3.5, "y": 1},
{"label": "R", "matrix": [1, 5], "x": 4.5, "y": 1},
{"label": "T", "matrix": [1, 6], "x": 5.5, "y": 1},
{"label": "Y", "matrix": [1, 7], "x": 6.5, "y": 1},
{"label": "U", "matrix": [1, 8], "x": 7.5, "y": 1},
{"label": "I", "matrix": [1, 9], "x": 8.5, "y": 1},
{"label": "O", "matrix": [1, 10], "x": 9.5, "y": 1},
{"label": "P", "matrix": [1, 11], "x": 10.5, "y": 1},
{"label": "{", "matrix": [1, 12], "x": 11.5, "y": 1},
{"label": "}", "matrix": [1, 13], "x": 12.5, "y": 1},
{"label": "|", "matrix": [1, 14], "x": 13.5, "y": 1, "w": 1.5},
{"label": "End", "matrix": [1, 15], "x": 15, "y": 1},
{"label": "Caps Lock", "matrix": [2, 0], "x": 0, "y": 2, "w": 1.25},
{"label": "A", "matrix": [2, 2], "x": 1.75, "y": 2},
{"label": "S", "matrix": [2, 3], "x": 2.75, "y": 2},
{"label": "D", "matrix": [2, 4], "x": 3.75, "y": 2},
{"label": "F", "matrix": [2, 5], "x": 4.75, "y": 2},
{"label": "G", "matrix": [2, 6], "x": 5.75, "y": 2},
{"label": "H", "matrix": [2, 7], "x": 6.75, "y": 2},
{"label": "J", "matrix": [2, 8], "x": 7.75, "y": 2},
{"label": "K", "matrix": [2, 9], "x": 8.75, "y": 2},
{"label": "L", "matrix": [2, 10], "x": 9.75, "y": 2},
{"label": ":", "matrix": [2, 11], "x": 10.75, "y": 2},
{"label": "\"", "matrix": [2, 12], "x": 11.75, "y": 2},
{"label": "Enter", "matrix": [2, 14], "x": 12.75, "y": 2, "w": 2.25},
{"label": "PgUp", "matrix": [2, 15], "x": 15, "y": 2},
{"label": "Shift", "matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"label": "Z", "matrix": [3, 2], "x": 2.25, "y": 3},
{"label": "X", "matrix": [3, 3], "x": 3.25, "y": 3},
{"label": "C", "matrix": [3, 4], "x": 4.25, "y": 3},
{"label": "V", "matrix": [3, 5], "x": 5.25, "y": 3},
{"label": "B", "matrix": [3, 6], "x": 6.25, "y": 3},
{"label": "N", "matrix": [3, 7], "x": 7.25, "y": 3},
{"label": "M", "matrix": [3, 8], "x": 8.25, "y": 3},
{"label": "<", "matrix": [3, 9], "x": 9.25, "y": 3},
{"label": ">", "matrix": [3, 10], "x": 10.25, "y": 3},
{"label": "?", "matrix": [3, 11], "x": 11.25, "y": 3},
{"label": "Shift", "matrix": [3, 13], "x": 12.25, "y": 3, "w": 1.75},
{"label": "Up", "matrix": [3, 14], "x": 14, "y": 3},
{"label": "PgDn", "matrix": [3, 15], "x": 15, "y": 3},
{"label": "Ctrl", "matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"label": "Win", "matrix": [4, 2], "x": 1.5, "y": 4},
{"label": "Alt", "matrix": [4, 3], "x": 2.5, "y": 4, "w": 1.5},
{"matrix": [4, 7], "x": 4, "y": 4, "w": 7},
{"label": "Alt", "matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"label": "Left", "matrix": [4, 13], "x": 13, "y": 4},
{"label": "Down", "matrix": [4, 14], "x": 14, "y": 4},
{"label": "Right", "matrix": [4, 15], "x": 15, "y": 4}
]
},
"LAYOUT_65_ansi_blocker_tsangan_split_bs": {
"layout": [
{"label": "Esc", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "!", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "@", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "#", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "$", "matrix": [0, 4], "x": 4, "y": 0},
{"label": "%", "matrix": [0, 5], "x": 5, "y": 0},
{"label": "^", "matrix": [0, 6], "x": 6, "y": 0},
{"label": "&", "matrix": [0, 7], "x": 7, "y": 0},
{"label": "*", "matrix": [0, 8], "x": 8, "y": 0},
{"label": "(", "matrix": [0, 9], "x": 9, "y": 0},
{"label": ")", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "_", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "+", "matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [0, 14], "x": 14, "y": 0},
{"label": "Home", "matrix": [0, 15], "x": 15, "y": 0},
{"label": "Tab", "matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"label": "Q", "matrix": [1, 2], "x": 1.5, "y": 1},
{"label": "W", "matrix": [1, 3], "x": 2.5, "y": 1},
{"label": "E", "matrix": [1, 4], "x": 3.5, "y": 1},
{"label": "R", "matrix": [1, 5], "x": 4.5, "y": 1},
{"label": "T", "matrix": [1, 6], "x": 5.5, "y": 1},
{"label": "Y", "matrix": [1, 7], "x": 6.5, "y": 1},
{"label": "U", "matrix": [1, 8], "x": 7.5, "y": 1},
{"label": "I", "matrix": [1, 9], "x": 8.5, "y": 1},
{"label": "O", "matrix": [1, 10], "x": 9.5, "y": 1},
{"label": "P", "matrix": [1, 11], "x": 10.5, "y": 1},
{"label": "{", "matrix": [1, 12], "x": 11.5, "y": 1},
{"label": "}", "matrix": [1, 13], "x": 12.5, "y": 1},
{"label": "|", "matrix": [1, 14], "x": 13.5, "y": 1, "w": 1.5},
{"label": "End", "matrix": [1, 15], "x": 15, "y": 1},
{"label": "Caps Lock", "matrix": [2, 0], "x": 0, "y": 2, "w": 1.25},
{"label": "A", "matrix": [2, 2], "x": 1.75, "y": 2},
{"label": "S", "matrix": [2, 3], "x": 2.75, "y": 2},
{"label": "D", "matrix": [2, 4], "x": 3.75, "y": 2},
{"label": "F", "matrix": [2, 5], "x": 4.75, "y": 2},
{"label": "G", "matrix": [2, 6], "x": 5.75, "y": 2},
{"label": "H", "matrix": [2, 7], "x": 6.75, "y": 2},
{"label": "J", "matrix": [2, 8], "x": 7.75, "y": 2},
{"label": "K", "matrix": [2, 9], "x": 8.75, "y": 2},
{"label": "L", "matrix": [2, 10], "x": 9.75, "y": 2},
{"label": ":", "matrix": [2, 11], "x": 10.75, "y": 2},
{"label": "\"", "matrix": [2, 12], "x": 11.75, "y": 2},
{"label": "Enter", "matrix": [2, 14], "x": 12.75, "y": 2, "w": 2.25},
{"label": "PgUp", "matrix": [2, 15], "x": 15, "y": 2},
{"label": "Shift", "matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"label": "Z", "matrix": [3, 2], "x": 2.25, "y": 3},
{"label": "X", "matrix": [3, 3], "x": 3.25, "y": 3},
{"label": "C", "matrix": [3, 4], "x": 4.25, "y": 3},
{"label": "V", "matrix": [3, 5], "x": 5.25, "y": 3},
{"label": "B", "matrix": [3, 6], "x": 6.25, "y": 3},
{"label": "N", "matrix": [3, 7], "x": 7.25, "y": 3},
{"label": "M", "matrix": [3, 8], "x": 8.25, "y": 3},
{"label": "<", "matrix": [3, 9], "x": 9.25, "y": 3},
{"label": ">", "matrix": [3, 10], "x": 10.25, "y": 3},
{"label": "?", "matrix": [3, 11], "x": 11.25, "y": 3},
{"label": "Shift", "matrix": [3, 13], "x": 12.25, "y": 3, "w": 1.75},
{"label": "Up", "matrix": [3, 14], "x": 14, "y": 3},
{"label": "PgDn", "matrix": [3, 15], "x": 15, "y": 3},
{"label": "Ctrl", "matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"label": "Win", "matrix": [4, 2], "x": 1.5, "y": 4},
{"label": "Alt", "matrix": [4, 3], "x": 2.5, "y": 4, "w": 1.5},
{"matrix": [4, 7], "x": 4, "y": 4, "w": 7},
{"label": "Alt", "matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"label": "Left", "matrix": [4, 13], "x": 13, "y": 4},
{"label": "Down", "matrix": [4, 14], "x": 14, "y": 4},
{"label": "Right", "matrix": [4, 15], "x": 15, "y": 4}
]
}
}
}
@@ -0,0 +1,24 @@
// Copyright 2024 ArcherKeyboard (archerkeyboard2022@gmail.com)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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_BSLS, KC_BSPC, KC_HOME,
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_END,
KC_CAPS, 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_PGUP,
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_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT
),
[1] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, _______, KC_DEL, _______,
_______, _______, _______, _______, _______, _______, _______, _______, KC_INS, _______, KC_PSCR, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_CALC, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_VOLU, _______,
_______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT
),
};
@@ -0,0 +1,24 @@
// Copyright 2024 ArcherKeyboard (archerkeyboard2022@gmail.com)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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_BSLS, KC_BSPC, KC_HOME,
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_END,
KC_CAPS, 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_PGUP,
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_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT
),
[1] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, _______, KC_DEL, _______,
_______, _______, _______, _______, _______, _______, _______, _______, KC_INS, _______, KC_PSCR, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_CALC, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_VOLU, _______,
_______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT
),
};
@@ -0,0 +1 @@
VIA_ENABLE = yes
@@ -0,0 +1,27 @@
# desire65
![desire65](https://i.imgur.com/bTjvGzC.jpg)
A desirable 65% keyboard
* Keyboard Maintainer: [ArcherKeyboard](https://github.com/akyp)
* Hardware Supported: Desire65 PCB
* Hardware Availability: [Open source on GitHub](https://github.com/akyp/desire65-pcb)
Make example for this keyboard (after setting up your build environment):
make archerkeyboard/desire65:default
Flashing example for this keyboard:
make archerkeyboard/desire65:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
* **Physical reset button**: Hold the "USB_BOOT" button on the back of the PCB (the one closest to the MCU) and briefly press the "RESET" button on the back of the PCB
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
-30
View File
@@ -16,36 +16,6 @@
#include "quantum.h"
#ifdef RGB_MATRIX_ENABLE
led_config_t g_led_config = { {
// Key Matrix to LED Index
{ 12, 11, 10, 9, 8, 7, 6, 5, 4, NO_LED, 3, 2, 1, 0 }, // 13 keys
{ 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 }, // 15 keys
{ 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28 }, // 15 keys
{ 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, NO_LED, 43 }, // 14 keys
{ 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, NO_LED, 58, 57 }, // 14 keys
{ 79, 78, 77, NO_LED, NO_LED, NO_LED, 76, NO_LED, NO_LED, NO_LED, 75, 74, 73, 72, 71 } // 9 keys
}, {
// LED Index to Physical Positon
{ 240, 0 }, { 224, 0 }, { 208, 0 }, { 192, 0 }, { 176, 0 }, { 160, 0 }, { 144, 0 }, { 128, 0 }, { 112, 0 }, { 96, 0 }, { 80, 0 }, { 64, 0 }, { 32, 0 },
{ 240, 13 }, { 224, 13 }, { 208, 13 }, { 192 , 13 }, { 176, 13 }, { 160, 13 }, { 144, 13 }, { 128, 13 }, { 112, 13 }, { 96, 13 }, { 80, 13 }, { 64, 13}, { 48, 13 }, { 32, 13 }, { 16, 13 },
{ 240, 26 }, { 224, 26 }, { 208, 26 }, { 192 , 26 }, { 176, 26 }, { 160, 26 }, { 144, 26 }, { 128, 26 }, { 112, 26 }, { 96, 26 }, { 80, 26 }, { 64, 26}, { 48, 26 }, { 32, 26 }, { 16, 26 },
{ 240, 39 }, { 216, 39 }, { 192 , 39 }, { 176, 39 }, { 160, 39 }, { 144, 39 }, { 128, 39 }, { 112, 39 }, { 96, 39 }, { 80, 39 }, { 64, 39}, { 48, 39 }, { 32, 39 }, { 16, 39 },
{ 240, 52 }, { 224, 52 }, { 208, 52 }, { 192 , 52 }, { 176, 52 }, { 160, 52 }, { 144, 52 }, { 128, 52 }, { 112, 52 }, { 96, 52 }, { 80, 52 }, { 64, 52}, { 48, 52 }, { 24, 52 },
{ 240, 64 }, { 224, 64 }, { 208, 64 }, { 192, 64 }, { 176, 64 }, { 112, 64 }, { 48, 64 }, { 32, 64 }, { 16, 64 },
{ 0, 26 }, { 0, 46 }, { 0, 64 }, { 48, 64 }, { 72, 64 }, { 104, 64 }, { 136, 64 }, { 168, 64 }, { 208, 64 }, { 232, 58 }, { 232, 45 }, { 232, 32 }, { 232, 20 }, { 232, 7 }, { 176, 0 }, { 112, 0 }
}, {
// LED Index to Flag
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
} };
#endif
#if defined(ENCODER_ENABLE) && !defined(ENCODER_MAP_ENABLE)
bool encoder_update_kb(uint8_t index, bool clockwise) {
if (!encoder_update_user(index, clockwise)) {
+117 -1
View File
@@ -58,7 +58,123 @@
},
"driver": "ws2812",
"max_brightness": 130,
"sleep": true
"sleep": true,
"layout": [
{"matrix": [0, 13], "x": 193, "y": 0, "flags": 4},
{"matrix": [0, 12], "x": 179, "y": 0, "flags": 4},
{"matrix": [0, 11], "x": 165, "y": 0, "flags": 4},
{"matrix": [0, 10], "x": 152, "y": 0, "flags": 4},
{"matrix": [0, 8], "x": 131, "y": 0, "flags": 4},
{"matrix": [0, 7], "x": 117, "y": 0, "flags": 4},
{"matrix": [0, 6], "x": 103, "y": 0, "flags": 4},
{"matrix": [0, 5], "x": 90, "y": 0, "flags": 4},
{"matrix": [0, 4], "x": 69, "y": 0, "flags": 4},
{"matrix": [0, 3], "x": 55, "y": 0, "flags": 4},
{"matrix": [0, 2], "x": 41, "y": 0, "flags": 4},
{"matrix": [0, 1], "x": 28, "y": 0, "flags": 4},
{"matrix": [0, 0], "x": 0, "y": 0, "flags": 1},
{"matrix": [1, 14], "x": 224, "y": 12, "flags": 1},
{"matrix": [1, 13], "x": 186, "y": 12, "flags": 1},
{"matrix": [1, 12], "x": 165, "y": 12, "flags": 4},
{"matrix": [1, 11], "x": 152, "y": 12, "flags": 4},
{"matrix": [1, 10], "x": 138, "y": 12, "flags": 4},
{"matrix": [1, 9], "x": 124, "y": 12, "flags": 4},
{"matrix": [1, 8], "x": 110, "y": 12, "flags": 4},
{"matrix": [1, 7], "x": 96, "y": 12, "flags": 4},
{"matrix": [1, 6], "x": 83, "y": 12, "flags": 4},
{"matrix": [1, 5], "x": 69, "y": 12, "flags": 4},
{"matrix": [1, 4], "x": 55, "y": 12, "flags": 4},
{"matrix": [1, 3], "x": 41, "y": 12, "flags": 4},
{"matrix": [1, 2], "x": 28, "y": 12, "flags": 4},
{"matrix": [1, 1], "x": 14, "y": 12, "flags": 4},
{"matrix": [1, 0], "x": 0, "y": 12, "flags": 4},
{"matrix": [2, 14], "x": 224, "y": 24, "flags": 1},
{"matrix": [2, 13], "x": 190, "y": 24, "flags": 1},
{"matrix": [2, 12], "x": 172, "y": 24, "flags": 4},
{"matrix": [2, 11], "x": 159, "y": 24, "flags": 4},
{"matrix": [2, 10], "x": 145, "y": 24, "flags": 4},
{"matrix": [2, 9], "x": 131, "y": 24, "flags": 4},
{"matrix": [2, 8], "x": 117, "y": 24, "flags": 4},
{"matrix": [2, 7], "x": 103, "y": 24, "flags": 4},
{"matrix": [2, 6], "x": 90, "y": 24, "flags": 4},
{"matrix": [2, 5], "x": 76, "y": 24, "flags": 4},
{"matrix": [2, 4], "x": 62, "y": 24, "flags": 4},
{"matrix": [2, 3], "x": 48, "y": 24, "flags": 4},
{"matrix": [2, 2], "x": 34, "y": 24, "flags": 4},
{"matrix": [2, 1], "x": 21, "y": 24, "flags": 4},
{"matrix": [2, 0], "x": 3, "y": 24, "flags": 1},
{"matrix": [3, 14], "x": 224, "y": 37, "flags": 1},
{"matrix": [3, 12], "x": 184, "y": 37, "flags": 1},
{"matrix": [3, 11], "x": 162, "y": 37, "flags": 4},
{"matrix": [3, 10], "x": 148, "y": 37, "flags": 4},
{"matrix": [3, 9], "x": 134, "y": 37, "flags": 4},
{"matrix": [3, 8], "x": 121, "y": 37, "flags": 4},
{"matrix": [3, 7], "x": 107, "y": 37, "flags": 4},
{"matrix": [3, 6], "x": 93, "y": 37, "flags": 4},
{"matrix": [3, 5], "x": 79, "y": 37, "flags": 4},
{"matrix": [3, 4], "x": 65, "y": 37, "flags": 4},
{"matrix": [3, 3], "x": 52, "y": 37, "flags": 4},
{"matrix": [3, 2], "x": 38, "y": 37, "flags": 4},
{"matrix": [3, 1], "x": 24, "y": 37, "flags": 4},
{"matrix": [3, 0], "x": 5, "y": 37, "flags": 1},
{"matrix": [4, 14], "x": 224, "y": 49, "flags": 1},
{"matrix": [4, 13], "x": 196, "y": 52, "flags": 4},
{"matrix": [4, 11], "x": 174, "y": 49, "flags": 1},
{"matrix": [4, 10], "x": 155, "y": 49, "flags": 4},
{"matrix": [4, 9], "x": 141, "y": 49, "flags": 4},
{"matrix": [4, 8], "x": 128, "y": 49, "flags": 4},
{"matrix": [4, 7], "x": 114, "y": 49, "flags": 4},
{"matrix": [4, 6], "x": 100, "y": 49, "flags": 4},
{"matrix": [4, 5], "x": 86, "y": 49, "flags": 4},
{"matrix": [4, 4], "x": 72, "y": 49, "flags": 4},
{"matrix": [4, 3], "x": 59, "y": 49, "flags": 4},
{"matrix": [4, 2], "x": 45, "y": 49, "flags": 4},
{"matrix": [4, 1], "x": 31, "y": 49, "flags": 4},
{"matrix": [4, 0], "x": 9, "y": 49, "flags": 1},
{"matrix": [5, 14], "x": 210, "y": 64, "flags": 4},
{"matrix": [5, 13], "x": 196, "y": 64, "flags": 4},
{"matrix": [5, 12], "x": 183, "y": 64, "flags": 4},
{"matrix": [5, 11], "x": 157, "y": 61, "flags": 1},
{"matrix": [5, 10], "x": 140, "y": 61, "flags": 1},
{"matrix": [5, 6], "x": 88, "y": 61, "flags": 4},
{"matrix": [5, 2], "x": 36, "y": 61, "flags": 1},
{"matrix": [5, 1], "x": 19, "y": 61, "flags": 1},
{"matrix": [5, 0], "x": 2, "y": 61, "flags": 1},
{"x": 28, "y": 61, "flags": 2},
{"x": 56, "y": 61, "flags": 2},
{"x": 79, "y": 61, "flags": 2},
{"x": 107, "y": 61, "flags": 2},
{"x": 128, "y": 61, "flags": 2},
{"x": 170, "y": 61, "flags": 2},
{"x": 220, "y": 55, "flags": 2},
{"x": 220, "y": 43, "flags": 2},
{"x": 220, "y": 30, "flags": 2},
{"x": 220, "y": 18, "flags": 2},
{"x": 220, "y": 6, "flags": 2},
{"x": 141, "y": 0, "flags": 2},
{"x": 79, "y": 0, "flags": 2},
{"x": 0, "y": 24, "flags": 2},
{"x": 0, "y": 43, "flags": 2},
{"x": 0, "y": 61, "flags": 2}
]
},
"build": {
"lto": true
@@ -112,8 +112,9 @@
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 6], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 10], "x": 10, "y": 5.25, "w": 1.5},
{"matrix": [5, 11], "x": 11.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 10], "x": 10, "y": 5.25, "w": 1},
{"matrix": [5, 11], "x": 11, "y": 5.25, "w": 1},
{"matrix": [5, 9], "x": 12, "y": 5.25, "w": 1},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 14], "x": 15.25, "y": 5.5}
@@ -10,7 +10,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
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_DEL,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENTER, KC_PGUP,
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_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_all(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, OLED_TOGG,
@@ -18,6 +18,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, CLOCK_SET,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______
QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -10,7 +10,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
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_DEL,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENTER, KC_PGUP,
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_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_all(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, OLED_TOGG,
@@ -18,6 +18,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, CLOCK_SET,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______
QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -1,8 +1,8 @@
/* Copyright 2022 @fOmey
/* Copyright 2024 Cipulot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@@ -16,4 +16,4 @@
#pragma once
#define RGB_MATRIX_LED_COUNT 96
#define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 2
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2024 Eason
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define WS2812_SPI_DRIVER SPID2
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2024 Eason
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define HAL_USE_SPI TRUE
#include_next <halconf.h>
+177
View File
@@ -0,0 +1,177 @@
{
"keyboard_name": "Void65h",
"manufacturer": "Eason",
"url": "",
"maintainer": "Eason",
"usb": {
"vid": "0x51D7",
"pid": "0x5517",
"device_version": "0.0.1",
"force_nkro": true
},
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"indicators": {
"caps_lock": "C13"
},
"matrix_pins": {
"rows": ["A15", "B3", "B4", "B5", "B6"],
"cols": ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "B0", "B1", "B10", "B11", "B12", "B13", "B14", "B15", "A8"]
},
"diode_direction": "ROW2COL",
"processor": "STM32F103",
"bootloader": "uf2boot",
"layout_aliases": {
"LAYOUT_all": "LAYOUT_65_ansi_blocker_tsangan_split_bs"
},
"community_layouts": ["65_ansi_blocker_tsangan", "65_ansi_blocker_tsangan_split_bs"]
"layouts": {
"LAYOUT_65_ansi_blocker_tsangan_split_bs": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0},
{"matrix": [0, 5], "x": 5, "y": 0},
{"matrix": [0, 6], "x": 6, "y": 0},
{"matrix": [0, 7], "x": 7, "y": 0},
{"matrix": [0, 8], "x": 8, "y": 0},
{"matrix": [0, 9], "x": 9, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [0, 14], "x": 14, "y": 0},
{"matrix": [0, 15], "x": 15, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"matrix": [1, 1], "x": 1.5, "y": 1},
{"matrix": [1, 2], "x": 2.5, "y": 1},
{"matrix": [1, 3], "x": 3.5, "y": 1},
{"matrix": [1, 4], "x": 4.5, "y": 1},
{"matrix": [1, 5], "x": 5.5, "y": 1},
{"matrix": [1, 6], "x": 6.5, "y": 1},
{"matrix": [1, 7], "x": 7.5, "y": 1},
{"matrix": [1, 8], "x": 8.5, "y": 1},
{"matrix": [1, 9], "x": 9.5, "y": 1},
{"matrix": [1, 10], "x": 10.5, "y": 1},
{"matrix": [1, 11], "x": 11.5, "y": 1},
{"matrix": [1, 12], "x": 12.5, "y": 1},
{"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
{"matrix": [1, 14], "x": 15, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
{"matrix": [2, 1], "x": 1.75, "y": 2},
{"matrix": [2, 2], "x": 2.75, "y": 2},
{"matrix": [2, 3], "x": 3.75, "y": 2},
{"matrix": [2, 4], "x": 4.75, "y": 2},
{"matrix": [2, 5], "x": 5.75, "y": 2},
{"matrix": [2, 6], "x": 6.75, "y": 2},
{"matrix": [2, 7], "x": 7.75, "y": 2},
{"matrix": [2, 8], "x": 8.75, "y": 2},
{"matrix": [2, 9], "x": 9.75, "y": 2},
{"matrix": [2, 10], "x": 10.75, "y": 2},
{"matrix": [2, 11], "x": 11.75, "y": 2},
{"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
{"matrix": [2, 14], "x": 15, "y": 2},
{"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"matrix": [3, 2], "x": 2.25, "y": 3},
{"matrix": [3, 3], "x": 3.25, "y": 3},
{"matrix": [3, 4], "x": 4.25, "y": 3},
{"matrix": [3, 5], "x": 5.25, "y": 3},
{"matrix": [3, 6], "x": 6.25, "y": 3},
{"matrix": [3, 7], "x": 7.25, "y": 3},
{"matrix": [3, 8], "x": 8.25, "y": 3},
{"matrix": [3, 9], "x": 9.25, "y": 3},
{"matrix": [3, 10], "x": 10.25, "y": 3},
{"matrix": [3, 11], "x": 11.25, "y": 3},
{"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
{"matrix": [3, 13], "x": 14, "y": 3},
{"matrix": [3, 14], "x": 15, "y": 3},
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"matrix": [4, 1], "x": 1.5, "y": 4},
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
{"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
{"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"matrix": [4, 12], "x": 13, "y": 4},
{"matrix": [4, 13], "x": 14, "y": 4},
{"matrix": [4, 14], "x": 15, "y": 4}
]
},
"LAYOUT_65_ansi_blocker_tsangan": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0},
{"matrix": [0, 5], "x": 5, "y": 0},
{"matrix": [0, 6], "x": 6, "y": 0},
{"matrix": [0, 7], "x": 7, "y": 0},
{"matrix": [0, 8], "x": 8, "y": 0},
{"matrix": [0, 9], "x": 9, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
{"matrix": [0, 15], "x": 15, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"matrix": [1, 1], "x": 1.5, "y": 1},
{"matrix": [1, 2], "x": 2.5, "y": 1},
{"matrix": [1, 3], "x": 3.5, "y": 1},
{"matrix": [1, 4], "x": 4.5, "y": 1},
{"matrix": [1, 5], "x": 5.5, "y": 1},
{"matrix": [1, 6], "x": 6.5, "y": 1},
{"matrix": [1, 7], "x": 7.5, "y": 1},
{"matrix": [1, 8], "x": 8.5, "y": 1},
{"matrix": [1, 9], "x": 9.5, "y": 1},
{"matrix": [1, 10], "x": 10.5, "y": 1},
{"matrix": [1, 11], "x": 11.5, "y": 1},
{"matrix": [1, 12], "x": 12.5, "y": 1},
{"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
{"matrix": [1, 14], "x": 15, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
{"matrix": [2, 1], "x": 1.75, "y": 2},
{"matrix": [2, 2], "x": 2.75, "y": 2},
{"matrix": [2, 3], "x": 3.75, "y": 2},
{"matrix": [2, 4], "x": 4.75, "y": 2},
{"matrix": [2, 5], "x": 5.75, "y": 2},
{"matrix": [2, 6], "x": 6.75, "y": 2},
{"matrix": [2, 7], "x": 7.75, "y": 2},
{"matrix": [2, 8], "x": 8.75, "y": 2},
{"matrix": [2, 9], "x": 9.75, "y": 2},
{"matrix": [2, 10], "x": 10.75, "y": 2},
{"matrix": [2, 11], "x": 11.75, "y": 2},
{"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
{"matrix": [2, 14], "x": 15, "y": 2},
{"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"matrix": [3, 2], "x": 2.25, "y": 3},
{"matrix": [3, 3], "x": 3.25, "y": 3},
{"matrix": [3, 4], "x": 4.25, "y": 3},
{"matrix": [3, 5], "x": 5.25, "y": 3},
{"matrix": [3, 6], "x": 6.25, "y": 3},
{"matrix": [3, 7], "x": 7.25, "y": 3},
{"matrix": [3, 8], "x": 8.25, "y": 3},
{"matrix": [3, 9], "x": 9.25, "y": 3},
{"matrix": [3, 10], "x": 10.25, "y": 3},
{"matrix": [3, 11], "x": 11.25, "y": 3},
{"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
{"matrix": [3, 13], "x": 14, "y": 3},
{"matrix": [3, 14], "x": 15, "y": 3},
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"matrix": [4, 1], "x": 1.5, "y": 4},
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
{"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
{"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"matrix": [4, 12], "x": 13, "y": 4},
{"matrix": [4, 13], "x": 14, "y": 4},
{"matrix": [4, 14], "x": 15, "y": 4}
]
}
}
}
@@ -0,0 +1,21 @@
// Copyright 2024 Eason
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_all(
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, KC_TILD, KC_DEL,
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,
KC_CAPS, 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_LSFT, KC_UP, MO(1),
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_all(
KC_TILD, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -0,0 +1,21 @@
// Copyright 2024 Eason
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_all(
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, KC_TILD, KC_DEL,
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,
KC_CAPS, 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_LSFT, KC_UP, MO(1),
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_all(
KC_TILD, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -0,0 +1,2 @@
VIA_ENABLE = yes
LTO_ENABLE = yes
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2024 Eason
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include_next <mcuconf.h>
#undef STM32_SPI_USE_SPI2
#define STM32_SPI_USE_SPI2 TRUE
+27
View File
@@ -0,0 +1,27 @@
# void65h
![void65h](https://i.imgur.com/3Z3jNAS.jpg)
A customizable hotswap 65% keyboard.
* Keyboard Maintainer: [EASON](https://github.com/EasonQian1)
* Hardware Supported: void65h
* Hardware Availability: [anorexus](https://anorexus.design/project/void)
Make example for this keyboard (after setting up your build environment):
make eason/void65h:default
Flashing example for this keyboard:
make eason/void65h:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down ESC in the keyboard then replug
* **Physical reset button**: Briefly press the button on the back of the PCB
* **Keycode in layout**: Press the key mapped to `QK_BOOT`
+68
View File
@@ -0,0 +1,68 @@
{
"manufacturer": "Falsonix",
"keyboard_name": "falsonix/fx19",
"maintainer": "falsonix",
"bootloader": "atmel-dfu",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true,
"rgblight": true
},
"rgblight": {
"led_count": 5,
"animations": {
"rainbow_mood": true,
"rainbow_swirl": true
},
"default": {
"animation": "rainbow_swirl"
}
},
"ws2812": {
"pin": "F7"
},
"matrix_pins": {
"cols": ["C7", "C6", "B6", "B5"],
"rows": ["F0", "F1", "F4", "F5", "F6"]
},
"processor": "atmega32u4",
"url": "",
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0x4658"
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [0, 0], "x":0, "y":0},
{"matrix": [0, 1], "x":1, "y":0},
{"matrix": [0, 2], "x":2, "y":0},
{"matrix": [0, 3], "x":3, "y":0},
{"matrix": [1, 0], "x":0, "y":1},
{"matrix": [1, 1], "x":1, "y":1},
{"matrix": [1, 2], "x":2, "y":1},
{"matrix": [2, 0], "x":0, "y":2},
{"matrix": [2, 1], "x":1, "y":2},
{"matrix": [2, 2], "x":2, "y":2},
{"matrix": [2, 3], "x":3, "y":2, "h": 2},
{"matrix": [3, 0], "x":0, "y":3},
{"matrix": [3, 1], "x":1, "y":3},
{"matrix": [3, 2], "x":2, "y":3},
{"matrix": [4, 0], "x":0, "y":4},
{"matrix": [4, 1], "x":1, "y":4},
{"matrix": [4, 2], "x":2, "y":4},
{"matrix": [4, 3], "x":3, "y":4, "h": 2}
]
}
}
}
@@ -0,0 +1,27 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
*┌───┬───┬───┬───┐
* Num│ / │ * │ - │
*├───┼───┼───┼───┤
*│ 7 │ 8 │ 9 │ + │
*├───┼───┼───┤ │
*│ 4 │ 5 │ 6 │ │
*├───┼───┼───┤───┤
*│ 1 │ 2 │ 3 │ │
*├───┼───┼───┤Ent│
*│Win│ 0 │ . │ │
*┴───┴───┴───┴───┘
*/
[0] = LAYOUT(
KC_LNUM, KC_PSLS, KC_PAST, KC_PMNS,
KC_P7, KC_P8, KC_P9,
KC_P4, KC_P5, KC_P6, KC_PPLS,
KC_P1, KC_P2, KC_P3,
KC_RWIN, KC_P0, KC_PDOT, KC_PENT
)
};
+26
View File
@@ -0,0 +1,26 @@
# falsonix/fx19
![falsonix/fx19](https://i.imgur.com/UGExzJl.png)
A small, 18-key number pad for use with modern computers. (Yes, the name says 19 and this is due to me miscounting the keys and realizing only after I'd named everything in firmware and hardware). Includes RGB for maximum performance.
* Keyboard Maintainer: [falsonix](https://github.com/falsonix)
* Hardware Supported: *FX19 Numpads*
* Hardware Availability: *DIY by the enduser*
Make example for this keyboard (after setting up your build environment):
make falsonix/fx19:default
Flashing example for this keyboard:
make falsonix/fx19:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 2 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (the top left key) and plug in the keyboard
* **Physical reset button**: Briefly press the button on the front of the PCB
-20
View File
@@ -1,20 +0,0 @@
/*
Copyright 2019 marhalloweenvt
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define RGB_MATRIX_LED_COUNT 83
+95 -1
View File
@@ -57,6 +57,100 @@
"solid_splash": true,
"solid_multisplash": true
},
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0, "flags": 1},
{"matrix": [0, 1], "x": 15, "y": 0, "flags": 4},
{"matrix": [0, 2], "x": 30, "y": 0, "flags": 4},
{"matrix": [0, 3], "x": 45, "y": 0, "flags": 4},
{"matrix": [0, 4], "x": 60, "y": 0, "flags": 4},
{"matrix": [0, 5], "x": 75, "y": 0, "flags": 4},
{"matrix": [0, 6], "x": 90, "y": 0, "flags": 4},
{"matrix": [0, 7], "x": 105, "y": 0, "flags": 4},
{"matrix": [0, 8], "x": 119, "y": 0, "flags": 4},
{"matrix": [0, 9], "x": 134, "y": 0, "flags": 4},
{"matrix": [0, 10], "x": 149, "y": 0, "flags": 4},
{"matrix": [0, 11], "x": 164, "y": 0, "flags": 4},
{"matrix": [0, 12], "x": 179, "y": 0, "flags": 4},
{"matrix": [0, 13], "x": 194, "y": 0, "flags": 1},
{"x": 202, "y": 0, "flags": 1},
{"matrix": [0, 14], "x": 209, "y": 0, "flags": 1},
{"matrix": [0, 15], "x": 224, "y": 0, "flags": 4},
{"x": 224, "y": 8, "flags": 2},
{"matrix": [1, 15], "x": 224, "y": 16, "flags": 4},
{"matrix": [1, 14], "x": 205, "y": 16, "flags": 1},
{"matrix": [1, 12], "x": 187, "y": 16, "flags": 4},
{"matrix": [1, 11], "x": 172, "y": 16, "flags": 4},
{"matrix": [1, 10], "x": 157, "y": 16, "flags": 4},
{"matrix": [1, 9], "x": 142, "y": 16, "flags": 4},
{"matrix": [1, 8], "x": 127, "y": 16, "flags": 4},
{"matrix": [1, 7], "x": 112, "y": 16, "flags": 4},
{"matrix": [1, 6], "x": 97, "y": 16, "flags": 4},
{"matrix": [1, 5], "x": 82, "y": 16, "flags": 4},
{"matrix": [1, 4], "x": 67, "y": 16, "flags": 4},
{"matrix": [1, 3], "x": 52, "y": 16, "flags": 4},
{"matrix": [1, 2], "x": 37, "y": 16, "flags": 4},
{"matrix": [1, 1], "x": 22, "y": 16, "flags": 4},
{"matrix": [1, 0], "x": 4, "y": 16, "flags": 1},
{"x": 0, "y": 8, "flags": 2},
{"x": 0, "y": 24, "flags": 2},
{"matrix": [2, 0], "x": 6, "y": 32, "flags": 1},
{"matrix": [2, 1], "x": 26, "y": 32, "flags": 4},
{"matrix": [2, 2], "x": 41, "y": 32, "flags": 4},
{"matrix": [2, 3], "x": 56, "y": 32, "flags": 4},
{"matrix": [2, 4], "x": 71, "y": 32, "flags": 4},
{"matrix": [2, 5], "x": 86, "y": 32, "flags": 4},
{"matrix": [2, 6], "x": 101, "y": 32, "flags": 4},
{"matrix": [2, 7], "x": 116, "y": 32, "flags": 4},
{"matrix": [2, 8], "x": 131, "y": 32, "flags": 4},
{"matrix": [2, 9], "x": 146, "y": 32, "flags": 4},
{"matrix": [2, 10], "x": 161, "y": 32, "flags": 4},
{"matrix": [2, 11], "x": 175, "y": 32, "flags": 4},
{"matrix": [2, 12], "x": 190, "y": 32, "flags": 4},
{"x": 200, "y": 32, "flags": 1},
{"matrix": [2, 14], "x": 207, "y": 32, "flags": 1},
{"matrix": [2, 15], "x": 224, "y": 32, "flags": 4},
{"x": 224, "y": 24, "flags": 2},
{"x": 224, "y": 40, "flags": 2},
{"matrix": [3, 15], "x": 224, "y": 48, "flags": 4},
{"matrix": [3, 14], "x": 209, "y": 48, "flags": 4},
{"matrix": [3, 12], "x": 189, "y": 48, "flags": 1},
{"matrix": [3, 10], "x": 168, "y": 48, "flags": 4},
{"matrix": [3, 9], "x": 153, "y": 48, "flags": 4},
{"matrix": [3, 8], "x": 138, "y": 48, "flags": 4},
{"matrix": [3, 7], "x": 123, "y": 48, "flags": 4},
{"matrix": [3, 6], "x": 108, "y": 48, "flags": 4},
{"matrix": [3, 5], "x": 93, "y": 48, "flags": 4},
{"matrix": [3, 4], "x": 78, "y": 48, "flags": 4},
{"matrix": [3, 3], "x": 63, "y": 48, "flags": 4},
{"matrix": [3, 2], "x": 49, "y": 48, "flags": 4},
{"matrix": [3, 1], "x": 34, "y": 48, "flags": 4},
{"matrix": [3, 0], "x": 9, "y": 48, "flags": 1},
{"x": 0, "y": 40, "flags": 2},
{"x": 0, "y": 56, "flags": 2},
{"matrix": [4, 0], "x": 2, "y": 64, "flags": 1},
{"x": 4, "y": 64, "flags": 1},
{"matrix": [4, 1], "x": 21, "y": 64, "flags": 1},
{"x": 26, "y": 64, "flags": 1},
{"matrix": [4, 2], "x": 39, "y": 64, "flags": 1},
{"matrix": [4, 5], "x": 95, "y": 64, "flags": 4},
{"x": 105, "y": 64, "flags": 4},
{"matrix": [4, 9], "x": 151, "y": 64, "flags": 1},
{"matrix": [4, 10], "x": 170, "y": 64, "flags": 1},
{"x": 172, "y": 64, "flags": 1},
{"matrix": [4, 12], "x": 194, "y": 64, "flags": 4},
{"matrix": [4, 14], "x": 209, "y": 64, "flags": 4},
{"matrix": [4, 15], "x": 224, "y": 64, "flags": 4},
{"x": 224, "y": 56, "flags": 2}
],
"driver": "ws2812",
"led_flush_limit": 26,
"led_process_limit": 4,
@@ -84,7 +178,7 @@
}
},
"matrix_pins": {
"cols": ["E6", "F0", "F1", "F4", "F5", "F6", "F7", "B0", "B1", "B2", "B3", "B7", "D0", "D1", "D2", "D3", "D7"],
"cols": ["E6", "F0", "F1", "F4", "F5", "F6", "F7", "B0", "B1", "B2", "B3", "B7", "D0", "D1", "D2", "D3"],
"rows": ["C7", "C6", "B6", "B5", "D5"]
},
"diode_direction": "COL2ROW",
+2 -20
View File
@@ -16,26 +16,7 @@
#include "quantum.h"
led_config_t g_led_config = { {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
{ 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17 },
{ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 },
{ 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51 },
{ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82 }
}, {
{ 0, 0 }, { 15, 0 }, { 30, 0 }, { 45, 0 }, { 60, 0 }, { 75, 0 }, { 90, 0 }, {105, 0 }, {120, 0 }, {135, 0 }, {150, 0 }, {165, 0 }, {180, 0 }, {195, 0 }, {205, 0 }, {210, 0 }, {224, 0 },
{ 224,16 }, {224, 16 }, {210, 16 }, {180, 16 }, {165, 16 }, {150, 16 }, {135, 16 }, {120, 16 }, {105, 16 }, { 90, 16 }, { 75, 16 }, { 60, 16 }, { 45, 16 }, { 30, 16 }, { 15, 16 }, { 0, 16 }, { 0, 16 },
{ 0, 32 }, { 0, 32 }, { 15, 32 }, { 30, 32 }, { 45, 32 }, { 60, 32 }, { 75, 32 }, { 90, 32 }, {105, 32 }, {120, 32 }, {135, 32 }, {150, 32 }, {165, 32 }, {190, 32 }, {205, 32 }, {210, 32 }, {224, 32 },
{ 224, 8 }, {224, 48 }, {210, 48 }, {195, 48 }, {180, 48 }, {150, 48 }, {135, 48 }, {120, 48 }, {105, 48 }, { 90, 48 }, { 75, 48 }, { 60, 48 }, { 45, 48 }, { 30, 48 }, { 15, 48 }, { 0, 48 }, { 0, 48 },
{ 0, 64 }, { 0, 64 }, { 0, 64 }, { 15, 64 }, { 15, 64 }, { 40, 64 }, { 90, 64 }, {105, 64 }, {150, 64 }, {180, 64 }, {180, 64 }, {195, 64 }, {210, 64 }, {220, 64 }, {224, 64 }
}, {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 2,
2, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
2, 2, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2
} };
#ifdef RGB_MATRIX_ENABLE
void suspend_power_down_kb(void)
{
rgb_matrix_set_suspend_state(true);
@@ -47,3 +28,4 @@ void suspend_wakeup_init_kb(void)
rgb_matrix_set_suspend_state(false);
suspend_wakeup_init_user();
}
#endif
@@ -0,0 +1,125 @@
{
"manufacturer": "KPrepublic",
"keyboard_name": "JJ50 rev2",
"maintainer": "qmk",
"backlight": {
"breathing": true,
"levels": 5,
"pin": "B7"
},
"bootloader": "atmel-dfu",
"build": {
"lto": true
},
"diode_direction": "COL2ROW",
"features": {
"backlight": true,
"bootmagic": true,
"extrakey": true,
"mousekey": true,
"nkro": false,
"rgblight": true
},
"matrix_pins": {
"cols": ["B1", "B0", "F7", "F0", "C7", "C6", "B6", "B5", "B4", "D7", "D6", "D4"],
"rows": ["D3", "D5", "E6", "F1", "F4"]
},
"processor": "atmega32u4",
"rgblight": {
"animations": {
"alternating": true,
"breathing": true,
"christmas": true,
"knight": true,
"rainbow_mood": true,
"rainbow_swirl": true,
"rgb_test": true,
"snake": true,
"static_gradient": true,
"twinkle": true
},
"brightness_steps": 8,
"hue_steps": 8,
"led_count": 6,
"saturation_steps": 8
},
"url": "",
"usb": {
"device_version": "2.0.0",
"pid": "0x0050",
"vid": "0x4B50"
},
"ws2812": {
"driver": "i2c"
},
"community_layouts": ["ortho_5x12"],
"layout_aliases": {
"LAYOUT": "LAYOUT_ortho_5x12"
},
"layouts": {
"LAYOUT_ortho_5x12": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0},
{"matrix": [0, 5], "x": 5, "y": 0},
{"matrix": [0, 6], "x": 6, "y": 0},
{"matrix": [0, 7], "x": 7, "y": 0},
{"matrix": [0, 8], "x": 8, "y": 0},
{"matrix": [0, 9], "x": 9, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1},
{"matrix": [1, 1], "x": 1, "y": 1},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1},
{"matrix": [1, 5], "x": 5, "y": 1},
{"matrix": [1, 6], "x": 6, "y": 1},
{"matrix": [1, 7], "x": 7, "y": 1},
{"matrix": [1, 8], "x": 8, "y": 1},
{"matrix": [1, 9], "x": 9, "y": 1},
{"matrix": [1, 10], "x": 10, "y": 1},
{"matrix": [1, 11], "x": 11, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2},
{"matrix": [2, 1], "x": 1, "y": 2},
{"matrix": [2, 2], "x": 2, "y": 2},
{"matrix": [2, 3], "x": 3, "y": 2},
{"matrix": [2, 4], "x": 4, "y": 2},
{"matrix": [2, 5], "x": 5, "y": 2},
{"matrix": [2, 6], "x": 6, "y": 2},
{"matrix": [2, 7], "x": 7, "y": 2},
{"matrix": [2, 8], "x": 8, "y": 2},
{"matrix": [2, 9], "x": 9, "y": 2},
{"matrix": [2, 10], "x": 10, "y": 2},
{"matrix": [2, 11], "x": 11, "y": 2},
{"matrix": [3, 0], "x": 0, "y": 3},
{"matrix": [3, 1], "x": 1, "y": 3},
{"matrix": [3, 2], "x": 2, "y": 3},
{"matrix": [3, 3], "x": 3, "y": 3},
{"matrix": [3, 4], "x": 4, "y": 3},
{"matrix": [3, 5], "x": 5, "y": 3},
{"matrix": [3, 6], "x": 6, "y": 3},
{"matrix": [3, 7], "x": 7, "y": 3},
{"matrix": [3, 8], "x": 8, "y": 3},
{"matrix": [3, 9], "x": 9, "y": 3},
{"matrix": [3, 10], "x": 10, "y": 3},
{"matrix": [3, 11], "x": 11, "y": 3},
{"matrix": [4, 0], "x": 0, "y": 4},
{"matrix": [4, 1], "x": 1, "y": 4},
{"matrix": [4, 2], "x": 2, "y": 4},
{"matrix": [4, 3], "x": 3, "y": 4},
{"matrix": [4, 4], "x": 4, "y": 4},
{"matrix": [4, 5], "x": 5, "y": 4},
{"matrix": [4, 6], "x": 6, "y": 4},
{"matrix": [4, 7], "x": 7, "y": 4},
{"matrix": [4, 8], "x": 8, "y": 4},
{"matrix": [4, 9], "x": 9, "y": 4},
{"matrix": [4, 10], "x": 10, "y": 4},
{"matrix": [4, 11], "x": 11, "y": 4}
]
}
}
}
@@ -0,0 +1,169 @@
{
"manufacturer": "auaera",
"keyboard_name": "Bunnygirl65",
"maintainer": "MaiTheSan",
"bootloader": "stm32-dfu",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"matrix_pins": {
"cols": ["A10", "A0", "A9", "C13", "A1", "A2", "B11", "B10", "B1", "B0", "A7", "A6", "A5", "A4", "C14"],
"rows": ["B4", "A15", "A3", "A8", "B14"]
},
"processor": "STM32F072",
"url": "",
"usb": {
"device_version": "1.0.0",
"force_nkro": true,
"pid": "0x00A2",
"vid": "0x5350"
},
"community_layouts": ["65_ansi_blocker_tsangan", "65_ansi_blocker_tsangan_split_bs"],
"layouts": {
"LAYOUT_65_ansi_blocker_tsangan": {
"layout": [
{"label": "K00", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "K01", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "K02", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "K03", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "K04", "matrix": [0, 4], "x": 4, "y": 0},
{"label": "K05", "matrix": [0, 5], "x": 5, "y": 0},
{"label": "K06", "matrix": [0, 6], "x": 6, "y": 0},
{"label": "K07", "matrix": [0, 7], "x": 7, "y": 0},
{"label": "K08", "matrix": [0, 8], "x": 8, "y": 0},
{"label": "K09", "matrix": [0, 9], "x": 9, "y": 0},
{"label": "K0A", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "K0B", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "K0C", "matrix": [0, 12], "x": 12, "y": 0},
{"label": "K0D", "matrix": [0, 13], "x": 13, "y": 0},
{"label": "K2D", "matrix": [2, 13], "x": 14, "y": 0, "w": 2},
{"label": "K10", "matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"label": "K11", "matrix": [1, 1], "x": 1.5, "y": 1},
{"label": "K12", "matrix": [1, 2], "x": 2.5, "y": 1},
{"label": "K13", "matrix": [1, 3], "x": 3.5, "y": 1},
{"label": "K14", "matrix": [1, 4], "x": 4.5, "y": 1},
{"label": "K15", "matrix": [1, 5], "x": 5.5, "y": 1},
{"label": "K16", "matrix": [1, 6], "x": 6.5, "y": 1},
{"label": "K17", "matrix": [1, 7], "x": 7.5, "y": 1},
{"label": "K18", "matrix": [1, 8], "x": 8.5, "y": 1},
{"label": "K19", "matrix": [1, 9], "x": 9.5, "y": 1},
{"label": "K1A", "matrix": [1, 10], "x": 10.5, "y": 1},
{"label": "K1B", "matrix": [1, 11], "x": 11.5, "y": 1},
{"label": "K1C", "matrix": [1, 12], "x": 12.5, "y": 1},
{"label": "K1D", "matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
{"label": "K1E", "matrix": [1, 14], "x": 15, "y": 1},
{"label": "K20", "matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
{"label": "K21", "matrix": [2, 1], "x": 1.75, "y": 2},
{"label": "K22", "matrix": [2, 2], "x": 2.75, "y": 2},
{"label": "K23", "matrix": [2, 3], "x": 3.75, "y": 2},
{"label": "K24", "matrix": [2, 4], "x": 4.75, "y": 2},
{"label": "K25", "matrix": [2, 5], "x": 5.75, "y": 2},
{"label": "K26", "matrix": [2, 6], "x": 6.75, "y": 2},
{"label": "K27", "matrix": [2, 7], "x": 7.75, "y": 2},
{"label": "K28", "matrix": [2, 8], "x": 8.75, "y": 2},
{"label": "K29", "matrix": [2, 9], "x": 9.75, "y": 2},
{"label": "K2A", "matrix": [2, 10], "x": 10.75, "y": 2},
{"label": "K2B", "matrix": [2, 11], "x": 11.75, "y": 2},
{"label": "K2C", "matrix": [2, 12], "x": 12.75, "y": 2, "w": 2.25},
{"label": "K2E", "matrix": [2, 14], "x": 15, "y": 2},
{"label": "K30", "matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"label": "K32", "matrix": [3, 2], "x": 2.25, "y": 3},
{"label": "K33", "matrix": [3, 3], "x": 3.25, "y": 3},
{"label": "K34", "matrix": [3, 4], "x": 4.25, "y": 3},
{"label": "K35", "matrix": [3, 5], "x": 5.25, "y": 3},
{"label": "K36", "matrix": [3, 6], "x": 6.25, "y": 3},
{"label": "K37", "matrix": [3, 7], "x": 7.25, "y": 3},
{"label": "K38", "matrix": [3, 8], "x": 8.25, "y": 3},
{"label": "K39", "matrix": [3, 9], "x": 9.25, "y": 3},
{"label": "K3A", "matrix": [3, 10], "x": 10.25, "y": 3},
{"label": "K3B", "matrix": [3, 11], "x": 11.25, "y": 3},
{"label": "K3C", "matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
{"label": "K3D", "matrix": [3, 13], "x": 14, "y": 3},
{"label": "K3E", "matrix": [3, 14], "x": 15, "y": 3},
{"label": "K40", "matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"label": "K41", "matrix": [4, 1], "x": 1.5, "y": 4},
{"label": "K42", "matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
{"label": "K46", "matrix": [4, 7], "x": 4, "y": 4, "w": 7},
{"label": "K4B", "matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"label": "K4C", "matrix": [4, 12], "x": 13, "y": 4},
{"label": "K4D", "matrix": [4, 13], "x": 14, "y": 4},
{"label": "K4E", "matrix": [4, 14], "x": 15, "y": 4}
]
},
"LAYOUT_65_ansi_blocker_tsangan_split_bs": {
"layout": [
{"label": "K00", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "K01", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "K02", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "K03", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "K04", "matrix": [0, 4], "x": 4, "y": 0},
{"label": "K05", "matrix": [0, 5], "x": 5, "y": 0},
{"label": "K06", "matrix": [0, 6], "x": 6, "y": 0},
{"label": "K07", "matrix": [0, 7], "x": 7, "y": 0},
{"label": "K08", "matrix": [0, 8], "x": 8, "y": 0},
{"label": "K09", "matrix": [0, 9], "x": 9, "y": 0},
{"label": "K0A", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "K0B", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "K0C", "matrix": [0, 12], "x": 12, "y": 0},
{"label": "K0D", "matrix": [0, 13], "x": 13, "y": 0},
{"label": "K2D", "matrix": [2, 13], "x": 14, "y": 0},
{"label": "K0E", "matrix": [0, 14], "x": 15, "y": 0},
{"label": "K10", "matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
{"label": "K11", "matrix": [1, 1], "x": 1.5, "y": 1},
{"label": "K12", "matrix": [1, 2], "x": 2.5, "y": 1},
{"label": "K13", "matrix": [1, 3], "x": 3.5, "y": 1},
{"label": "K14", "matrix": [1, 4], "x": 4.5, "y": 1},
{"label": "K15", "matrix": [1, 5], "x": 5.5, "y": 1},
{"label": "K16", "matrix": [1, 6], "x": 6.5, "y": 1},
{"label": "K17", "matrix": [1, 7], "x": 7.5, "y": 1},
{"label": "K18", "matrix": [1, 8], "x": 8.5, "y": 1},
{"label": "K19", "matrix": [1, 9], "x": 9.5, "y": 1},
{"label": "K1A", "matrix": [1, 10], "x": 10.5, "y": 1},
{"label": "K1B", "matrix": [1, 11], "x": 11.5, "y": 1},
{"label": "K1C", "matrix": [1, 12], "x": 12.5, "y": 1},
{"label": "K1D", "matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
{"label": "K1E", "matrix": [1, 14], "x": 15, "y": 1},
{"label": "K20", "matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
{"label": "K21", "matrix": [2, 1], "x": 1.75, "y": 2},
{"label": "K22", "matrix": [2, 2], "x": 2.75, "y": 2},
{"label": "K23", "matrix": [2, 3], "x": 3.75, "y": 2},
{"label": "K24", "matrix": [2, 4], "x": 4.75, "y": 2},
{"label": "K25", "matrix": [2, 5], "x": 5.75, "y": 2},
{"label": "K26", "matrix": [2, 6], "x": 6.75, "y": 2},
{"label": "K27", "matrix": [2, 7], "x": 7.75, "y": 2},
{"label": "K28", "matrix": [2, 8], "x": 8.75, "y": 2},
{"label": "K29", "matrix": [2, 9], "x": 9.75, "y": 2},
{"label": "K2A", "matrix": [2, 10], "x": 10.75, "y": 2},
{"label": "K2B", "matrix": [2, 11], "x": 11.75, "y": 2},
{"label": "K2C", "matrix": [2, 12], "x": 12.75, "y": 2, "w": 2.25},
{"label": "K2E", "matrix": [2, 14], "x": 15, "y": 2},
{"label": "K30", "matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
{"label": "K32", "matrix": [3, 2], "x": 2.25, "y": 3},
{"label": "K33", "matrix": [3, 3], "x": 3.25, "y": 3},
{"label": "K34", "matrix": [3, 4], "x": 4.25, "y": 3},
{"label": "K35", "matrix": [3, 5], "x": 5.25, "y": 3},
{"label": "K36", "matrix": [3, 6], "x": 6.25, "y": 3},
{"label": "K37", "matrix": [3, 7], "x": 7.25, "y": 3},
{"label": "K38", "matrix": [3, 8], "x": 8.25, "y": 3},
{"label": "K39", "matrix": [3, 9], "x": 9.25, "y": 3},
{"label": "K3A", "matrix": [3, 10], "x": 10.25, "y": 3},
{"label": "K3B", "matrix": [3, 11], "x": 11.25, "y": 3},
{"label": "K3C", "matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
{"label": "K3D", "matrix": [3, 13], "x": 14, "y": 3},
{"label": "K3E", "matrix": [3, 14], "x": 15, "y": 3},
{"label": "K40", "matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
{"label": "K41", "matrix": [4, 1], "x": 1.5, "y": 4},
{"label": "K42", "matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
{"label": "K46", "matrix": [4, 7], "x": 4, "y": 4, "w": 7},
{"label": "K4B", "matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
{"label": "K4C", "matrix": [4, 12], "x": 13, "y": 4},
{"label": "K4D", "matrix": [4, 13], "x": 14, "y": 4},
{"label": "K4E", "matrix": [4, 14], "x": 15, "y": 4}
]
}
}
}
@@ -0,0 +1,48 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
* │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Bsp│Bsp│Hom│
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │PgU│
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PgD│
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
* │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │End│
* ├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴───┴┬─┬───┼───┼───┤
* │Ctrl │GUI│Alt │ │ Fn│ │ ← │ ↓ │ → │
* └─────┴───┴─────┴───────────────────────────┴─────┘ └───┴───┴───┘
*/
[0] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, KC_BSPC, KC_HOME,
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,
KC_CAPS, 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_END,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
),
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
* │ ` │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│Del│Del│ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤
* │ │ │ │ │ │ │Ins│ │ │ │ │PSc│Scr│Pause│ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
* │ │ │ │ │ │ │ │Mut│Vl-│Vl+│ │ │ │ │
* ├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴───┴┬─┬───┼───┼───┤
* │ │ │ │ │ │ │ │ │ │
* └─────┴───┴─────┴───────────────────────────┴─────┘ └───┴───┴───┘
*/
[1] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, KC_DEL, KC_DEL, _______,
_______, _______, _______, _______, _______, _______, KC_INS, _______, _______, _______, _______, KC_PSCR, KC_SCRL, KC_PAUS, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -0,0 +1,48 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
* │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Bsp│Bsp│Hom│
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │PgU│
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PgD│
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
* │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │End│
* ├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴───┴┬─┬───┼───┼───┤
* │Ctrl │GUI│Alt │ │ Fn│ │ ← │ ↓ │ → │
* └─────┴───┴─────┴───────────────────────────┴─────┘ └───┴───┴───┘
*/
[0] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, KC_BSPC, KC_HOME,
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,
KC_CAPS, 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_END,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
),
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
* │ ` │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│Del│Del│ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┤
* │ │ │ │ │ │ │Ins│ │ │ │ │PSc│Scr│Pause│ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
* │ │ │ │ │ │ │ │Mut│Vl-│Vl+│ │ │ │ │
* ├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴───┴┬─┬───┼───┼───┤
* │ │ │ │ │ │ │ │ │ │
* └─────┴───┴─────┴───────────────────────────┴─────┘ └───┴───┴───┘
*/
[1] = LAYOUT_65_ansi_blocker_tsangan_split_bs(
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, KC_DEL, KC_DEL, _______,
_______, _______, _______, _______, _______, _______, KC_INS, _______, _______, _______, _______, KC_PSCR, KC_SCRL, KC_PAUS, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______
)
};
@@ -0,0 +1 @@
VIA_ENABLE = yes
@@ -0,0 +1,27 @@
# BunnyGirl65
![BunnyGirl65](https://i.imgur.com/APqNMhc.jpeg)
A Wibu 60% keyboard PCB Design by inspire of Nekomata Okayu and can fit many keyboard case
* Keyboard Maintainer: [Mai The San](https://github.com/maithesan)
* Hardware Supported: BunnyGirl65
* Hardware Availability: [Waifu.Works](https://discord.gg/waifuworks)
Make example for this keyboard (after setting up your build environment):
make sawnsprojects/bunnygirl65:default
Flashing example for this keyboard:
make sawnsprojects/bunnygirl65:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
+72 -35
View File
@@ -1,8 +1,8 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
import json
import shutil
from typing import List, Union
from typing import Dict, List, Union
from pathlib import Path
from dotty_dict import dotty, Dotty
from milc import cli
@@ -13,6 +13,9 @@ from qmk.info import keymap_json
from qmk.keymap import locate_keymap
from qmk.path import is_under_qmk_firmware, is_under_qmk_userspace
# These must be kept in the order in which they're applied to $(TARGET) in the makefiles in order to ensure consistency.
TARGET_FILENAME_MODIFIERS = ['FORCE_LAYOUT', 'CONVERT_TO']
class BuildTarget:
def __init__(self, keyboard: str, keymap: str, json: Union[dict, Dotty] = None):
@@ -22,25 +25,25 @@ class BuildTarget:
self._parallel = 1
self._clean = False
self._compiledb = False
self._target = f'{self._keyboard_safe}_{self.keymap}'
self._intermediate_output = Path(f'{INTERMEDIATE_OUTPUT_PREFIX}{self._target}')
self._generated_files_path = self._intermediate_output / 'src'
self._extra_args = {}
self._json = json.to_dict() if isinstance(json, Dotty) else json
def __str__(self):
return f'{self.keyboard}:{self.keymap}'
def __repr__(self):
if len(self._extra_args.items()) > 0:
return f'BuildTarget(keyboard={self.keyboard}, keymap={self.keymap}, extra_args={json.dumps(self._extra_args, sort_keys=True)})'
return f'BuildTarget(keyboard={self.keyboard}, keymap={self.keymap})'
def __lt__(self, __value: object) -> bool:
return self.__repr__() < __value.__repr__()
def __eq__(self, __value: object) -> bool:
if not isinstance(__value, BuildTarget):
return False
return self.__repr__() == __value.__repr__()
def __ne__(self, __value: object) -> bool:
return not self.__eq__(__value)
def __hash__(self) -> int:
return self.__repr__().__hash__()
@@ -72,7 +75,34 @@ class BuildTarget:
def dotty(self) -> Dotty:
return dotty(self.json)
def _common_make_args(self, dry_run: bool = False, build_target: str = None):
@property
def extra_args(self) -> Dict[str, str]:
return {k: v for k, v in self._extra_args.items()}
@extra_args.setter
def extra_args(self, ex_args: Dict[str, str]):
if ex_args is not None and isinstance(ex_args, dict):
self._extra_args = {k: v for k, v in ex_args.items()}
def target_name(self, **env_vars) -> str:
# Work out the intended target name
target = f'{self._keyboard_safe}_{self.keymap}'
vars = self._all_vars(**env_vars)
for modifier in TARGET_FILENAME_MODIFIERS:
if modifier in vars:
target += f"_{vars[modifier]}"
return target
def _all_vars(self, **env_vars) -> Dict[str, str]:
vars = {k: v for k, v in env_vars.items()}
for k, v in self._extra_args.items():
vars[k] = v
return vars
def _intermediate_output(self, **env_vars) -> Path:
return Path(f'{INTERMEDIATE_OUTPUT_PREFIX}{self.target_name(**env_vars)}')
def _common_make_args(self, dry_run: bool = False, build_target: str = None, **env_vars):
compile_args = [
find_make(),
*get_make_parallel_args(self._parallel),
@@ -98,14 +128,17 @@ class BuildTarget:
f'KEYBOARD={self.keyboard}',
f'KEYMAP={self.keymap}',
f'KEYBOARD_FILESAFE={self._keyboard_safe}',
f'TARGET={self._target}',
f'INTERMEDIATE_OUTPUT={self._intermediate_output}',
f'TARGET={self._keyboard_safe}_{self.keymap}', # don't use self.target_name() here, it's rebuilt on the makefile side
f'VERBOSE={verbose}',
f'COLOR={color}',
'SILENT=false',
'QMK_BIN="qmk"',
])
vars = self._all_vars(**env_vars)
for k, v in vars.items():
compile_args.append(f'{k}={v}')
return compile_args
def prepare_build(self, build_target: str = None, dry_run: bool = False, **env_vars) -> None:
@@ -150,6 +183,8 @@ class KeyboardKeymapBuildTarget(BuildTarget):
super().__init__(keyboard=keyboard, keymap=keymap, json=json)
def __repr__(self):
if len(self._extra_args.items()) > 0:
return f'KeyboardKeymapTarget(keyboard={self.keyboard}, keymap={self.keymap}, extra_args={self._extra_args})'
return f'KeyboardKeymapTarget(keyboard={self.keyboard}, keymap={self.keymap})'
def _load_json(self):
@@ -159,15 +194,13 @@ class KeyboardKeymapBuildTarget(BuildTarget):
pass
def compile_command(self, build_target: str = None, dry_run: bool = False, **env_vars) -> List[str]:
compile_args = self._common_make_args(dry_run=dry_run, build_target=build_target)
for key, value in env_vars.items():
compile_args.append(f'{key}={value}')
compile_args = self._common_make_args(dry_run=dry_run, build_target=build_target, **env_vars)
# Need to override the keymap path if the keymap is a userspace directory.
# This also ensures keyboard aliases as per `keyboard_aliases.hjson` still work if the userspace has the keymap
# in an equivalent historical location.
keymap_location = locate_keymap(self.keyboard, self.keymap)
vars = self._all_vars(**env_vars)
keymap_location = locate_keymap(self.keyboard, self.keymap, force_layout=vars.get('FORCE_LAYOUT'))
if is_under_qmk_userspace(keymap_location) and not is_under_qmk_firmware(keymap_location):
keymap_directory = keymap_location.parent
compile_args.extend([
@@ -196,47 +229,51 @@ class JsonKeymapBuildTarget(BuildTarget):
super().__init__(keyboard=json['keyboard'], keymap=json['keymap'], json=json)
self._keymap_json = self._generated_files_path / 'keymap.json'
def __repr__(self):
if len(self._extra_args.items()) > 0:
return f'JsonKeymapTarget(keyboard={self.keyboard}, keymap={self.keymap}, path={self.json_path}, extra_args={self._extra_args})'
return f'JsonKeymapTarget(keyboard={self.keyboard}, keymap={self.keymap}, path={self.json_path})'
def _load_json(self):
pass # Already loaded in constructor
def prepare_build(self, build_target: str = None, dry_run: bool = False, **env_vars) -> None:
intermediate_output = self._intermediate_output(**env_vars)
generated_files_path = intermediate_output / 'src'
keymap_json = generated_files_path / 'keymap.json'
if self._clean:
if self._intermediate_output.exists():
shutil.rmtree(self._intermediate_output)
if intermediate_output.exists():
shutil.rmtree(intermediate_output)
# begin with making the deepest folder in the tree
self._generated_files_path.mkdir(exist_ok=True, parents=True)
generated_files_path.mkdir(exist_ok=True, parents=True)
# Compare minified to ensure consistent comparison
new_content = json.dumps(self.json, separators=(',', ':'))
if self._keymap_json.exists():
old_content = json.dumps(json.loads(self._keymap_json.read_text(encoding='utf-8')), separators=(',', ':'))
if keymap_json.exists():
old_content = json.dumps(json.loads(keymap_json.read_text(encoding='utf-8')), separators=(',', ':'))
if old_content == new_content:
new_content = None
# Write the keymap.json file if different so timestamps are only updated
# if the content changes -- running `make` won't treat it as modified.
if new_content:
self._keymap_json.write_text(new_content, encoding='utf-8')
keymap_json.write_text(new_content, encoding='utf-8')
def compile_command(self, build_target: str = None, dry_run: bool = False, **env_vars) -> List[str]:
compile_args = self._common_make_args(dry_run=dry_run, build_target=build_target)
compile_args = self._common_make_args(dry_run=dry_run, build_target=build_target, **env_vars)
intermediate_output = self._intermediate_output(**env_vars)
generated_files_path = intermediate_output / 'src'
keymap_json = generated_files_path / 'keymap.json'
compile_args.extend([
f'MAIN_KEYMAP_PATH_1={self._intermediate_output}',
f'MAIN_KEYMAP_PATH_2={self._intermediate_output}',
f'MAIN_KEYMAP_PATH_3={self._intermediate_output}',
f'MAIN_KEYMAP_PATH_4={self._intermediate_output}',
f'MAIN_KEYMAP_PATH_5={self._intermediate_output}',
f'KEYMAP_JSON={self._keymap_json}',
f'KEYMAP_PATH={self._generated_files_path}',
f'MAIN_KEYMAP_PATH_1={intermediate_output}',
f'MAIN_KEYMAP_PATH_2={intermediate_output}',
f'MAIN_KEYMAP_PATH_3={intermediate_output}',
f'MAIN_KEYMAP_PATH_4={intermediate_output}',
f'MAIN_KEYMAP_PATH_5={intermediate_output}',
f'KEYMAP_JSON={keymap_json}',
f'KEYMAP_PATH={generated_files_path}',
])
for key, value in env_vars.items():
compile_args.append(f'{key}={value}')
return compile_args
-5
View File
@@ -53,11 +53,6 @@ def _check_avr_gcc_version():
version_number = ESSENTIAL_BINARIES['avr-gcc']['output'].strip()
cli.log.info('Found avr-gcc version %s', version_number)
parsed_version = _parse_gcc_version(version_number)
if parsed_version['major'] > 8:
cli.log.warning('{fg_yellow}We do not recommend avr-gcc newer than 8. Downgrading to 8.x is recommended.')
return CheckStatus.WARNING
return CheckStatus.OK
+8 -1
View File
@@ -18,11 +18,18 @@ def _detect_json_format(file, json_data):
"""
json_encoder = None
try:
validate(json_data, 'qmk.user_repo.v1')
validate(json_data, 'qmk.user_repo.v1_1')
json_encoder = UserspaceJSONEncoder
except ValidationError:
pass
if json_encoder is None:
try:
validate(json_data, 'qmk.user_repo.v1')
json_encoder = UserspaceJSONEncoder
except ValidationError:
pass
if json_encoder is None:
try:
validate(json_data, 'qmk.keyboard.v1')
+17 -7
View File
@@ -7,6 +7,7 @@ from typing import List
from pathlib import Path
from subprocess import DEVNULL
from milc import cli
import shlex
from qmk.constants import QMK_FIRMWARE
from qmk.commands import find_make, get_make_parallel_args, build_environment
@@ -26,7 +27,8 @@ def mass_compile_targets(targets: List[BuildTarget], clean: bool, dry_run: bool,
if dry_run:
cli.log.info('Compilation targets:')
for target in sorted(targets, key=lambda t: (t.keyboard, t.keymap)):
cli.log.info(f"{{fg_cyan}}qmk compile -kb {target.keyboard} -km {target.keymap}{{fg_reset}}")
extra_args = ' '.join([f"-e {shlex.quote(f'{k}={v}')}" for k, v in target.extra_args.items()])
cli.log.info(f"{{fg_cyan}}qmk compile -kb {target.keyboard} -km {target.keymap} {extra_args}{{fg_reset}}")
else:
if clean:
cli.run([make_cmd, 'clean'], capture_output=False, stdin=DEVNULL)
@@ -36,18 +38,26 @@ def mass_compile_targets(targets: List[BuildTarget], clean: bool, dry_run: bool,
for target in sorted(targets, key=lambda t: (t.keyboard, t.keymap)):
keyboard_name = target.keyboard
keymap_name = target.keymap
keyboard_safe = keyboard_name.replace('/', '_')
target_filename = target.target_name(**env)
target.configure(parallel=1) # We ignore parallelism on a per-build basis as we defer to the parent make invocation
target.prepare_build(**env) # If we've got json targets, allow them to write out any extra info to .build before we kick off `make`
command = target.compile_command(**env)
command[0] = '+@$(MAKE)' # Override the make so that we can use jobserver to handle parallelism
keyboard_safe = keyboard_name.replace('/', '_')
extra_args = '_'.join([f"{k}_{v}" for k, v in target.extra_args.items()])
build_log = f"{QMK_FIRMWARE}/.build/build.log.{os.getpid()}.{keyboard_safe}.{keymap_name}"
failed_log = f"{QMK_FIRMWARE}/.build/failed.log.{os.getpid()}.{keyboard_safe}.{keymap_name}"
target_suffix = ''
if len(extra_args) > 0:
build_log += f".{extra_args}"
failed_log += f".{extra_args}"
target_suffix = f"_{extra_args}"
# yapf: disable
f.write(
f"""\
all: {keyboard_safe}_{keymap_name}_binary
{keyboard_safe}_{keymap_name}_binary:
.PHONY: {target_filename}{target_suffix}_binary
all: {target_filename}{target_suffix}_binary
{target_filename}{target_suffix}_binary:
@rm -f "{build_log}" || true
@echo "Compiling QMK Firmware for target: '{keyboard_name}:{keymap_name}'..." >>"{build_log}"
{' '.join(command)} \\
@@ -65,9 +75,9 @@ all: {keyboard_safe}_{keymap_name}_binary
# yapf: disable
f.write(
f"""\
@rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{keymap_name}.elf" 2>/dev/null || true
@rm -rf "{QMK_FIRMWARE}/.build/{keyboard_safe}_{keymap_name}.map" 2>/dev/null || true
@rm -rf "{QMK_FIRMWARE}/.build/obj_{keyboard_safe}_{keymap_name}" || true
@rm -rf "{QMK_FIRMWARE}/.build/{target_filename}.elf" 2>/dev/null || true
@rm -rf "{QMK_FIRMWARE}/.build/{target_filename}.map" 2>/dev/null || true
@rm -rf "{QMK_FIRMWARE}/.build/obj_{target_filename}" || true
"""# noqa
)
# yapf: enable
+7 -3
View File
@@ -1,8 +1,9 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
from pathlib import Path
from milc import cli
from qmk.commands import parse_env_vars
from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE
from qmk.keyboard import keyboard_completer, keyboard_folder_or_all
from qmk.keymap import keymap_completer, is_keymap_target
@@ -12,12 +13,15 @@ from qmk.userspace import UserspaceDefs
@cli.argument('builds', nargs='*', arg_only=True, help="List of builds in form <keyboard>:<keymap>, or path to a keymap JSON file.")
@cli.argument('-kb', '--keyboard', type=keyboard_folder_or_all, completer=keyboard_completer, help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-km', '--keymap', completer=keymap_completer, help='The keymap to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-e', '--env', arg_only=True, action='append', default=[], help="Extra variables to set during build. May be passed multiple times.")
@cli.subcommand('Adds a build target to userspace `qmk.json`.')
def userspace_add(cli):
if not HAS_QMK_USERSPACE:
cli.log.error('Could not determine QMK userspace location. Please run `qmk doctor` or `qmk userspace-doctor` to diagnose.')
return False
build_env = None if len(cli.args.env) == 0 else parse_env_vars(cli.args.env)
userspace = UserspaceDefs(QMK_USERSPACE / 'qmk.json')
if len(cli.args.builds) > 0:
@@ -44,8 +48,8 @@ def userspace_add(cli):
cli.config.new_keymap.keyboard = cli.args.keyboard
cli.config.new_keymap.keymap = cli.args.keymap
if new_keymap(cli) is not False:
userspace.add_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap)
userspace.add_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap, build_env=build_env)
else:
userspace.add_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap)
userspace.add_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap, build_env=build_env)
return userspace.save()
+7 -3
View File
@@ -1,4 +1,4 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
from pathlib import Path
from milc import cli
@@ -12,6 +12,10 @@ from qmk.cli.mass_compile import mass_compile_targets
from qmk.util import maybe_exit_config
def _extra_arg_setter(target, extra_args):
target.extra_args = extra_args
@cli.argument('-t', '--no-temp', arg_only=True, action='store_true', help="Remove temporary files during build.")
@cli.argument('-j', '--parallel', type=int, default=1, help="Set the number of parallel make jobs; 0 means unlimited.")
@cli.argument('-c', '--clean', arg_only=True, action='store_true', help="Remove object files before compiling.")
@@ -33,8 +37,8 @@ def userspace_compile(cli):
if isinstance(e, Path):
build_targets.append(JsonKeymapBuildTarget(e))
elif isinstance(e, dict):
keyboard_keymap_targets.append((e['keyboard'], e['keymap']))
f = e['env'] if 'env' in e else None
keyboard_keymap_targets.append((e['keyboard'], e['keymap'], f))
if len(keyboard_keymap_targets) > 0:
build_targets.extend(search_keymap_targets(keyboard_keymap_targets))
+19 -4
View File
@@ -1,4 +1,4 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
from pathlib import Path
from dotty_dict import Dotty
@@ -13,6 +13,10 @@ from qmk.search import search_keymap_targets
from qmk.util import maybe_exit_config
def _extra_arg_setter(target, extra_args):
target.extra_args = extra_args
@cli.argument('-e', '--expand', arg_only=True, action='store_true', help="Expands any use of `all` for either keyboard or keymap.")
@cli.subcommand('Lists the build targets specified in userspace `qmk.json`.')
def userspace_list(cli):
@@ -26,11 +30,15 @@ def userspace_list(cli):
if cli.args.expand:
build_targets = []
keyboard_keymap_targets = []
for e in userspace.build_targets:
if isinstance(e, Path):
build_targets.append(e)
elif isinstance(e, dict) or isinstance(e, Dotty):
build_targets.extend(search_keymap_targets([(e['keyboard'], e['keymap'])]))
f = e['env'] if 'env' in e else None
keyboard_keymap_targets.append((e['keyboard'], e['keymap'], f))
if len(keyboard_keymap_targets) > 0:
build_targets.extend(search_keymap_targets(keyboard_keymap_targets))
else:
build_targets = userspace.build_targets
@@ -43,12 +51,19 @@ def userspace_list(cli):
# keyboard/keymap dict from userspace
keyboard = e['keyboard']
keymap = e['keymap']
extra_args = e.get('env')
elif isinstance(e, BuildTarget):
# BuildTarget from search_keymap_targets()
keyboard = e.keyboard
keymap = e.keymap
extra_args = e.extra_args
extra_args_str = ''
if extra_args is not None and len(extra_args) > 0:
extra_args_str = ', '.join([f'{{fg_cyan}}{k}={v}{{fg_reset}}' for k, v in extra_args.items()])
extra_args_str = f' ({{fg_cyan}}{extra_args_str}{{fg_reset}})'
if is_all_keyboards(keyboard) or is_keymap_target(keyboard_folder(keyboard), keymap):
cli.log.info(f'Keyboard: {{fg_cyan}}{keyboard}{{fg_reset}}, keymap: {{fg_cyan}}{keymap}{{fg_reset}}')
cli.log.info(f'Keyboard: {{fg_cyan}}{keyboard}{{fg_reset}}, keymap: {{fg_cyan}}{keymap}{{fg_reset}}{extra_args_str}')
else:
cli.log.warn(f'Keyboard: {{fg_cyan}}{keyboard}{{fg_reset}}, keymap: {{fg_cyan}}{keymap}{{fg_reset}} -- not found!')
cli.log.warn(f'Keyboard: {{fg_cyan}}{keyboard}{{fg_reset}}, keymap: {{fg_cyan}}{keymap}{{fg_reset}}{extra_args_str} -- not found!')
+7 -3
View File
@@ -1,8 +1,9 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
from pathlib import Path
from milc import cli
from qmk.commands import parse_env_vars
from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE
from qmk.keyboard import keyboard_completer, keyboard_folder_or_all
from qmk.keymap import keymap_completer
@@ -12,12 +13,15 @@ from qmk.userspace import UserspaceDefs
@cli.argument('builds', nargs='*', arg_only=True, help="List of builds in form <keyboard>:<keymap>, or path to a keymap JSON file.")
@cli.argument('-kb', '--keyboard', type=keyboard_folder_or_all, completer=keyboard_completer, help='The keyboard to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-km', '--keymap', completer=keymap_completer, help='The keymap to build a firmware for. Ignored when a configurator export is supplied.')
@cli.argument('-e', '--env', arg_only=True, action='append', default=[], help="Extra variables to set during build. May be passed multiple times.")
@cli.subcommand('Removes a build target from userspace `qmk.json`.')
def userspace_remove(cli):
if not HAS_QMK_USERSPACE:
cli.log.error('Could not determine QMK userspace location. Please run `qmk doctor` or `qmk userspace-doctor` to diagnose.')
return False
build_env = None if len(cli.args.env) == 0 else parse_env_vars(cli.args.env)
userspace = UserspaceDefs(QMK_USERSPACE / 'qmk.json')
if len(cli.args.builds) > 0:
@@ -29,9 +33,9 @@ def userspace_remove(cli):
for e in make_like_targets:
s = e.split(':')
userspace.remove_target(keyboard=s[0], keymap=s[1])
userspace.remove_target(keyboard=s[0], keymap=s[1], build_env=build_env)
else:
userspace.remove_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap)
userspace.remove_target(keyboard=cli.args.keyboard, keymap=cli.args.keymap, build_env=build_env)
return userspace.save()
+6 -1
View File
@@ -68,7 +68,7 @@ def parse_configurator_json(configurator_file):
return user_keymap
def build_environment(args):
def parse_env_vars(args):
"""Common processing for cli.args.env
"""
envs = {}
@@ -78,6 +78,11 @@ def build_environment(args):
envs[key] = value
else:
cli.log.warning('Invalid environment variable: %s', env)
return envs
def build_environment(args):
envs = parse_env_vars(args)
if HAS_QMK_USERSPACE:
envs['QMK_USERSPACE'] = Path(QMK_USERSPACE).resolve()
+12 -7
View File
@@ -212,7 +212,7 @@ def _validate(keyboard, info_data):
maybe_exit(1)
def info_json(keyboard):
def info_json(keyboard, force_layout=None):
"""Generate the info.json data for a specific keyboard.
"""
cur_dir = Path('keyboards')
@@ -255,6 +255,11 @@ def info_json(keyboard):
# Merge in data from <keyboard.c>
info_data = _extract_led_config(info_data, str(keyboard))
# Force a community layout if requested
community_layouts = info_data.get("community_layouts", [])
if force_layout in community_layouts:
info_data["community_layouts"] = [force_layout]
# Validate
_validate(keyboard, info_data)
@@ -988,25 +993,25 @@ def find_info_json(keyboard):
return [info_json for info_json in info_jsons if info_json.exists()]
def keymap_json_config(keyboard, keymap):
def keymap_json_config(keyboard, keymap, force_layout=None):
"""Extract keymap level config
"""
# TODO: resolve keymap.py and info.py circular dependencies
from qmk.keymap import locate_keymap
keymap_folder = locate_keymap(keyboard, keymap).parent
keymap_folder = locate_keymap(keyboard, keymap, force_layout=force_layout).parent
km_info_json = parse_configurator_json(keymap_folder / 'keymap.json')
return km_info_json.get('config', {})
def keymap_json(keyboard, keymap):
def keymap_json(keyboard, keymap, force_layout=None):
"""Generate the info.json data for a specific keymap.
"""
# TODO: resolve keymap.py and info.py circular dependencies
from qmk.keymap import locate_keymap
keymap_folder = locate_keymap(keyboard, keymap).parent
keymap_folder = locate_keymap(keyboard, keymap, force_layout=force_layout).parent
# Files to scan
keymap_config = keymap_folder / 'config.h'
@@ -1014,10 +1019,10 @@ def keymap_json(keyboard, keymap):
keymap_file = keymap_folder / 'keymap.json'
# Build the info.json file
kb_info_json = info_json(keyboard)
kb_info_json = info_json(keyboard, force_layout=force_layout)
# Merge in the data from keymap.json
km_info_json = keymap_json_config(keyboard, keymap) if keymap_file.exists() else {}
km_info_json = keymap_json_config(keyboard, keymap, force_layout=force_layout) if keymap_file.exists() else {}
deep_update(kb_info_json, km_info_json)
# Merge in the data from config.h, and rules.mk
+2 -2
View File
@@ -420,7 +420,7 @@ def write(keymap_json):
return write_file(keymap_file, keymap_content)
def locate_keymap(keyboard, keymap):
def locate_keymap(keyboard, keymap, force_layout=None):
"""Returns the path to a keymap for a specific keyboard.
"""
if not qmk.path.is_keyboard(keyboard):
@@ -459,7 +459,7 @@ def locate_keymap(keyboard, keymap):
return keymap_path
# Check community layouts as a fallback
info = info_json(keyboard)
info = info_json(keyboard, force_layout=force_layout)
community_parents = list(Path('layouts').glob('*/'))
if HAS_QMK_USERSPACE and (Path(QMK_USERSPACE) / "layouts").exists():
+99 -60
View File
@@ -1,11 +1,13 @@
"""Functions for searching through QMK keyboards and keymaps.
"""
from dataclasses import dataclass
import contextlib
import functools
import fnmatch
import json
import logging
import re
from typing import Callable, List, Optional, Tuple
from typing import Callable, Dict, List, Optional, Tuple, Union
from dotty_dict import dotty, Dotty
from milc import cli
@@ -15,7 +17,32 @@ from qmk.keyboard import list_keyboards, keyboard_folder
from qmk.keymap import list_keymaps, locate_keymap
from qmk.build_targets import KeyboardKeymapBuildTarget, BuildTarget
TargetInfo = Tuple[str, str, dict]
@dataclass
class KeyboardKeymapDesc:
keyboard: str
keymap: str
data: dict = None
extra_args: dict = None
def __hash__(self) -> int:
return self.keyboard.__hash__() ^ self.keymap.__hash__() ^ json.dumps(self.extra_args, sort_keys=True).__hash__()
def __lt__(self, other) -> bool:
return (self.keyboard, self.keymap, json.dumps(self.extra_args, sort_keys=True)) < (other.keyboard, other.keymap, json.dumps(other.extra_args, sort_keys=True))
def load_data(self):
data = keymap_json(self.keyboard, self.keymap)
self.data = data.to_dict() if isinstance(data, Dotty) else data
@property
def dotty(self) -> Dotty:
return dotty(self.data) if self.data is not None else None
def to_build_target(self) -> KeyboardKeymapBuildTarget:
target = KeyboardKeymapBuildTarget(keyboard=self.keyboard, keymap=self.keymap, json=self.data)
target.extra_args = self.extra_args
return target
# by using a class for filters, we dont need to worry about capturing values
@@ -36,7 +63,7 @@ class FilterFunction:
value: Optional[str]
func_name: str
apply: Callable[[TargetInfo], bool]
apply: Callable[[KeyboardKeymapDesc], bool]
def __init__(self, key, value):
self.key = key
@@ -46,33 +73,29 @@ class FilterFunction:
class Exists(FilterFunction):
func_name = "exists"
def apply(self, target_info: TargetInfo) -> bool:
_kb, _km, info = target_info
return self.key in info
def apply(self, target_info: KeyboardKeymapDesc) -> bool:
return self.key in target_info.data
class Absent(FilterFunction):
func_name = "absent"
def apply(self, target_info: TargetInfo) -> bool:
_kb, _km, info = target_info
return self.key not in info
def apply(self, target_info: KeyboardKeymapDesc) -> bool:
return self.key not in target_info.data
class Length(FilterFunction):
func_name = "length"
def apply(self, target_info: TargetInfo) -> bool:
_kb, _km, info = target_info
return (self.key in info and len(info[self.key]) == int(self.value))
def apply(self, target_info: KeyboardKeymapDesc) -> bool:
return (self.key in target_info.data and len(target_info.data[self.key]) == int(self.value))
class Contains(FilterFunction):
func_name = "contains"
def apply(self, target_info: TargetInfo) -> bool:
_kb, _km, info = target_info
return (self.key in info and self.value in info[self.key])
def apply(self, target_info: KeyboardKeymapDesc) -> bool:
return (self.key in target_info.data and self.value in target_info.data[self.key])
def _get_filter_class(func_name: str, key: str, value: str) -> Optional[FilterFunction]:
@@ -109,12 +132,12 @@ def ignore_logging():
_set_log_level(old)
def _all_keymaps(keyboard):
"""Returns a list of tuples of (keyboard, keymap) for all keymaps for the given keyboard.
def _all_keymaps(keyboard) -> List[KeyboardKeymapDesc]:
"""Returns a list of KeyboardKeymapDesc for all keymaps for the given keyboard.
"""
with ignore_logging():
keyboard = keyboard_folder(keyboard)
return [(keyboard, keymap) for keymap in list_keymaps(keyboard)]
return [KeyboardKeymapDesc(keyboard, keymap) for keymap in list_keymaps(keyboard)]
def _keymap_exists(keyboard, keymap):
@@ -124,85 +147,91 @@ def _keymap_exists(keyboard, keymap):
return keyboard if locate_keymap(keyboard, keymap) is not None else None
def _load_keymap_info(target: Tuple[str, str]) -> TargetInfo:
"""Returns a tuple of (keyboard, keymap, info.json) for the given keyboard/keymap combination.
def _load_keymap_info(target: KeyboardKeymapDesc) -> KeyboardKeymapDesc:
"""Ensures a KeyboardKeymapDesc has its data loaded.
"""
kb, km = target
with ignore_logging():
return (kb, km, keymap_json(kb, km))
target.load_data() # Ensure we load the data first
return target
def expand_make_targets(targets: List[str]) -> List[Tuple[str, str]]:
"""Expand a list of make targets into a list of (keyboard, keymap) tuples.
def expand_make_targets(targets: List[Union[str, Tuple[str, Dict[str, str]]]]) -> List[KeyboardKeymapDesc]:
"""Expand a list of make targets into a list of KeyboardKeymapDesc.
Caters for 'all' in either keyboard or keymap, or both.
"""
split_targets = []
for target in targets:
split_target = target.split(':')
extra_args = None
if isinstance(target, tuple):
split_target = target[0].split(':')
extra_args = target[1]
else:
split_target = target.split(':')
if len(split_target) != 2:
cli.log.error(f"Invalid build target: {target}")
return []
split_targets.append((split_target[0], split_target[1]))
split_targets.append(KeyboardKeymapDesc(split_target[0], split_target[1], extra_args=extra_args))
return expand_keymap_targets(split_targets)
def _expand_keymap_target(keyboard: str, keymap: str, all_keyboards: List[str] = None) -> List[Tuple[str, str]]:
"""Expand a keyboard input and keymap input into a list of (keyboard, keymap) tuples.
def _expand_keymap_target(target: KeyboardKeymapDesc, all_keyboards: List[str] = None) -> List[KeyboardKeymapDesc]:
"""Expand a keyboard input and keymap input into a list of KeyboardKeymapDesc.
Caters for 'all' in either keyboard or keymap, or both.
"""
if all_keyboards is None:
all_keyboards = list_keyboards()
if keyboard == 'all':
if keymap == 'all':
if target.keyboard == 'all':
if target.keymap == 'all':
cli.log.info('Retrieving list of all keyboards and keymaps...')
targets = []
for kb in parallel_map(_all_keymaps, all_keyboards):
targets.extend(kb)
for t in targets:
t.extra_args = target.extra_args
return targets
else:
cli.log.info(f'Retrieving list of keyboards with keymap "{keymap}"...')
keyboard_filter = functools.partial(_keymap_exists, keymap=keymap)
return [(kb, keymap) for kb in filter(lambda e: e is not None, parallel_map(keyboard_filter, all_keyboards))]
cli.log.info(f'Retrieving list of keyboards with keymap "{target.keymap}"...')
keyboard_filter = functools.partial(_keymap_exists, keymap=target.keymap)
return [KeyboardKeymapDesc(kb, target.keymap, extra_args=target.extra_args) for kb in filter(lambda e: e is not None, parallel_map(keyboard_filter, all_keyboards))]
else:
if keymap == 'all':
cli.log.info(f'Retrieving list of keymaps for keyboard "{keyboard}"...')
return _all_keymaps(keyboard)
if target.keymap == 'all':
cli.log.info(f'Retrieving list of keymaps for keyboard "{target.keyboard}"...')
targets = _all_keymaps(target.keyboard)
for t in targets:
t.extra_args = target.extra_args
return targets
else:
return [(keyboard, keymap)]
return [target]
def expand_keymap_targets(targets: List[Tuple[str, str]]) -> List[Tuple[str, str]]:
"""Expand a list of (keyboard, keymap) tuples inclusive of 'all', into a list of explicit (keyboard, keymap) tuples.
def expand_keymap_targets(targets: List[KeyboardKeymapDesc]) -> List[KeyboardKeymapDesc]:
"""Expand a list of KeyboardKeymapDesc inclusive of 'all', into a list of explicit KeyboardKeymapDesc.
"""
overall_targets = []
all_keyboards = list_keyboards()
for target in targets:
overall_targets.extend(_expand_keymap_target(target[0], target[1], all_keyboards))
overall_targets.extend(_expand_keymap_target(target, all_keyboards))
return list(sorted(set(overall_targets)))
def _construct_build_target_kb_km(e):
return KeyboardKeymapBuildTarget(keyboard=e[0], keymap=e[1])
def _construct_build_target(e: KeyboardKeymapDesc):
return e.to_build_target()
def _construct_build_target_kb_km_json(e):
return KeyboardKeymapBuildTarget(keyboard=e[0], keymap=e[1], json=e[2])
def _filter_keymap_targets(target_list: List[Tuple[str, str]], filters: List[str] = []) -> List[BuildTarget]:
"""Filter a list of (keyboard, keymap) tuples based on the supplied filters.
def _filter_keymap_targets(target_list: List[KeyboardKeymapDesc], filters: List[str] = []) -> List[KeyboardKeymapDesc]:
"""Filter a list of KeyboardKeymapDesc based on the supplied filters.
Optionally includes the values of the queried info.json keys.
"""
if len(filters) == 0:
cli.log.info('Preparing target list...')
targets = list(set(parallel_map(_construct_build_target_kb_km, target_list)))
targets = target_list
else:
cli.log.info('Parsing data for all matching keyboard/keymap combinations...')
valid_keymaps = [(e[0], e[1], dotty(e[2])) for e in parallel_map(_load_keymap_info, target_list)]
valid_targets = parallel_map(_load_keymap_info, target_list)
function_re = re.compile(r'^(?P<function>[a-zA-Z]+)\((?P<key>[a-zA-Z0-9_\.]+)(,\s*(?P<value>[^#]+))?\)$')
equals_re = re.compile(r'^(?P<key>[a-zA-Z0-9_\.]+)\s*=\s*(?P<value>[^#]+)$')
@@ -220,7 +249,7 @@ def _filter_keymap_targets(target_list: List[Tuple[str, str]], filters: List[str
if filter_class is None:
cli.log.warning(f'Unrecognized filter expression: {function_match.group(0)}')
continue
valid_keymaps = filter(filter_class.apply, valid_keymaps)
valid_targets = filter(filter_class.apply, valid_targets)
value_str = f", {{fg_cyan}}{value}{{fg_reset}}" if value is not None else ""
cli.log.info(f'Filtering on condition: {{fg_green}}{func_name}{{fg_reset}}({{fg_cyan}}{key}{{fg_reset}}{value_str})...')
@@ -234,32 +263,42 @@ def _filter_keymap_targets(target_list: List[Tuple[str, str]], filters: List[str
expr = fnmatch.translate(v)
rule = re.compile(f'^{expr}$', re.IGNORECASE)
def f(e):
lhs = e[2].get(k)
def f(e: KeyboardKeymapDesc):
lhs = e.dotty.get(k)
lhs = str(False if lhs is None else lhs)
return rule.search(lhs) is not None
return f
valid_keymaps = filter(_make_filter(key, value), valid_keymaps)
valid_targets = filter(_make_filter(key, value), valid_targets)
else:
cli.log.warning(f'Unrecognized filter expression: {filter_expr}')
continue
cli.log.info('Preparing target list...')
valid_keymaps = [(e[0], e[1], e[2].to_dict() if isinstance(e[2], Dotty) else e[2]) for e in valid_keymaps] # need to convert dotty_dict back to dict because it doesn't survive parallelisation
targets = list(set(parallel_map(_construct_build_target_kb_km_json, list(valid_keymaps))))
targets = list(sorted(set(valid_targets)))
return targets
def search_keymap_targets(targets: List[Tuple[str, str]] = [('all', 'default')], filters: List[str] = []) -> List[BuildTarget]:
def search_keymap_targets(targets: List[Union[Tuple[str, str], Tuple[str, str, Dict[str, str]]]] = [('all', 'default')], filters: List[str] = []) -> List[BuildTarget]:
"""Search for build targets matching the supplied criteria.
"""
return _filter_keymap_targets(expand_keymap_targets(targets), filters)
def _make_desc(e):
if len(e) == 3:
return KeyboardKeymapDesc(keyboard=e[0], keymap=e[1], extra_args=e[2])
else:
return KeyboardKeymapDesc(keyboard=e[0], keymap=e[1])
targets = map(_make_desc, targets)
targets = _filter_keymap_targets(expand_keymap_targets(targets), filters)
targets = list(set(parallel_map(_construct_build_target, list(targets))))
return sorted(targets)
def search_make_targets(targets: List[str], filters: List[str] = []) -> List[BuildTarget]:
def search_make_targets(targets: List[Union[str, Tuple[str, Dict[str, str]]]], filters: List[str] = []) -> List[BuildTarget]:
"""Search for build targets matching the supplied criteria.
"""
return _filter_keymap_targets(expand_make_targets(targets), filters)
targets = _filter_keymap_targets(expand_make_targets(targets), filters)
targets = list(set(parallel_map(_construct_build_target, list(targets))))
return sorted(targets)
+48 -18
View File
@@ -1,4 +1,4 @@
# Copyright 2023 Nick Brassel (@tzarc)
# Copyright 2023-2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
from os import environ
from pathlib import Path
@@ -77,31 +77,43 @@ class UserspaceDefs:
raise exception
# Iterate through each version of the schema, starting with the latest and decreasing to v1
try:
validate(json, 'qmk.user_repo.v1')
self.__load_v1(json)
success = True
except jsonschema.ValidationError as err:
exception.add('qmk.user_repo.v1', err)
schema_versions = [
('qmk.user_repo.v1_1', self.__load_v1_1), #
('qmk.user_repo.v1', self.__load_v1) #
]
for v in schema_versions:
schema = v[0]
loader = v[1]
try:
validate(json, schema)
loader(json)
success = True
break
except jsonschema.ValidationError as err:
exception.add(schema, err)
if not success:
raise exception
def save(self):
target_json = {
"userspace_version": "1.0", # Needs to match latest version
"userspace_version": "1.1", # Needs to match latest version
"build_targets": []
}
for e in self.build_targets:
if isinstance(e, dict):
target_json['build_targets'].append([e['keyboard'], e['keymap']])
entry = [e['keyboard'], e['keymap']]
if 'env' in e:
entry.append(e['env'])
target_json['build_targets'].append(entry)
elif isinstance(e, Path):
target_json['build_targets'].append(str(e.relative_to(self.path.parent)))
try:
# Ensure what we're writing validates against the latest version of the schema
validate(target_json, 'qmk.user_repo.v1')
validate(target_json, 'qmk.user_repo.v1_1')
except jsonschema.ValidationError as err:
cli.log.error(f'Could not save userspace file: {err}')
return False
@@ -114,7 +126,7 @@ class UserspaceDefs:
cli.log.info(f'Saved userspace file to {self.path}.')
return True
def add_target(self, keyboard=None, keymap=None, json_path=None, do_print=True):
def add_target(self, keyboard=None, keymap=None, build_env=None, json_path=None, do_print=True):
if json_path is not None:
# Assume we're adding a json filename/path
json_path = Path(json_path)
@@ -128,6 +140,8 @@ class UserspaceDefs:
elif keyboard is not None and keymap is not None:
# Both keyboard/keymap specified
e = {"keyboard": keyboard, "keymap": keymap}
if build_env is not None:
e['env'] = build_env
if e not in self.build_targets:
self.build_targets.append(e)
if do_print:
@@ -136,7 +150,7 @@ class UserspaceDefs:
if do_print:
cli.log.info(f'{keyboard}:{keymap} is already a userspace build target.')
def remove_target(self, keyboard=None, keymap=None, json_path=None, do_print=True):
def remove_target(self, keyboard=None, keymap=None, build_env=None, json_path=None, do_print=True):
if json_path is not None:
# Assume we're removing a json filename/path
json_path = Path(json_path)
@@ -150,6 +164,8 @@ class UserspaceDefs:
elif keyboard is not None and keymap is not None:
# Both keyboard/keymap specified
e = {"keyboard": keyboard, "keymap": keymap}
if build_env is not None:
e['env'] = build_env
if e in self.build_targets:
self.build_targets.remove(e)
if do_print:
@@ -160,12 +176,26 @@ class UserspaceDefs:
def __load_v1(self, json):
for e in json['build_targets']:
if isinstance(e, list) and len(e) == 2:
self.add_target(keyboard=e[0], keymap=e[1], do_print=False)
if isinstance(e, str):
p = self.path.parent / e
if p.exists() and p.suffix == '.json':
self.add_target(json_path=p, do_print=False)
self.__load_v1_target(e)
def __load_v1_1(self, json):
for e in json['build_targets']:
self.__load_v1_1_target(e)
def __load_v1_target(self, e):
if isinstance(e, list) and len(e) == 2:
self.add_target(keyboard=e[0], keymap=e[1], do_print=False)
if isinstance(e, str):
p = self.path.parent / e
if p.exists() and p.suffix == '.json':
self.add_target(json_path=p, do_print=False)
def __load_v1_1_target(self, e):
# v1.1 adds support for a third item in the build target tuple; kvp's for environment
if isinstance(e, list) and len(e) == 3:
self.add_target(keyboard=e[0], keymap=e[1], build_env=e[2], do_print=False)
else:
self.__load_v1_target(e)
class UserspaceValidationError(Exception):
+8 -12
View File
@@ -4,13 +4,10 @@
# Configuration
# The ChibiOS branches to mirror
chibios_branches="trunk stable_20.3.x stable_21.11.x"
# The ChibiOS tags to mirror
chibios_tags="ver20.3.1 ver20.3.2 ver20.3.3 ver20.3.4 ver21.11.1 ver21.11.2 ver21.11.3"
chibios_branches="trunk stable_21.11.x"
# The ChibiOS-Contrib branches to mirror
contrib_branches="chibios-20.3.x chibios-21.11.x"
contrib_branches="chibios-21.11.x"
################################
# Actions
@@ -46,6 +43,12 @@ fi
echo "Updating remotes..."
git fetch --all --tags --prune
echo "Ensure refs actually match up..."
for branch in $chibios_branches ; do
echo "Matching $branch..."
git update-ref refs/remotes/svn/$branch refs/remotes/qmk/svn-mirror/$branch
done
echo "Fetching latest from subversion..."
git svn fetch
@@ -56,13 +59,6 @@ for branch in $chibios_branches ; do
&& git push qmk svn-mirror/$branch
done
echo "Updating ChibiOS tags..."
for tagname in $chibios_tags ; do
echo "Creating tag 'svn-mirror/$tagname' from 'svn/tags/$tagname'..."
GIT_COMMITTER_DATE="$(git log -n1 --pretty=format:'%ad' svn/tags/$tagname)" git tag -f -a -m "Tagging $tagname" svn-mirror/$tagname svn/tags/$tagname
git push qmk svn-mirror/$tagname
done
cd "$contrib_dir"
if [[ -z "$(cat "$contrib_git_config" | grep '\[remote "qmk"\]')" ]] ; then