Anne Pro 2 Refactor (#16864)

* move RGB Matrix rules to keyboard level

* move PERMISSIVE_HOLD config to keyboard level

* annepro2.c: convert tabs to spaces

* refactor rules.mk files

Reformats each version's `rules.mk` file to be arranged more similarly to those of the rest of the keyboards in QMK.

No logic change.

* annepro2.c: allow compilation without RGB Matrix

Wraps the `led_enabled` definition and the `KC_AP_RGB_*` keycodes in `#ifdef RGB_MATRIX_ENABLE`, allowing successful compilation if the user sets `RGB_MATRIX_ENABLE = no`.

* rework readme files

Reworks the main `readme.md` file to be more friendly to GitHub viewing, and removes the single-line version-specific readme files (exposes the main readme to QMK Configurator users).

* info.json: update maintainer value

* info.json: apply friendly formatting
This commit is contained in:
James Young 2022-04-17 12:53:59 -07:00 committed by GitHub
parent a5a4597311
commit 7d60a141a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 211 additions and 503 deletions

View File

@ -42,11 +42,10 @@ static const SerialConfig ble_uart_config = {
static uint8_t led_mcu_wakeup[11] = {0x7b, 0x10, 0x43, 0x10, 0x03, 0x00, 0x00, 0x7d, 0x02, 0x01, 0x02}; static uint8_t led_mcu_wakeup[11] = {0x7b, 0x10, 0x43, 0x10, 0x03, 0x00, 0x00, 0x7d, 0x02, 0x01, 0x02};
static uint8_t led_enabled = 1;
ble_capslock_t ble_capslock = {._dummy = {0}, .caps_lock = false}; ble_capslock_t ble_capslock = {._dummy = {0}, .caps_lock = false};
#ifdef RGB_MATRIX_ENABLE #ifdef RGB_MATRIX_ENABLE
static uint8_t led_enabled = 1;
static uint8_t current_rgb_row = 0; static uint8_t current_rgb_row = 0;
#endif #endif
@ -227,69 +226,69 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
if(rgb_matrix_is_enabled()) ap2_led_disable(); if(rgb_matrix_is_enabled()) ap2_led_disable();
else ap2_led_enable(); else ap2_led_enable();
return true; return true;
#endif
case KC_AP_RGB_VAI: case KC_AP_RGB_VAI:
if (record->event.pressed) { if (record->event.pressed) {
if (get_mods() & MOD_MASK_SHIFT) { if (get_mods() & MOD_MASK_SHIFT) {
rgb_matrix_increase_hue(); rgb_matrix_increase_hue();
return false; return false;
} else if (get_mods() & MOD_MASK_CTRL) { } else if (get_mods() & MOD_MASK_CTRL) {
rgb_matrix_decrease_hue(); rgb_matrix_decrease_hue();
return false; return false;
} else { } else {
rgb_matrix_increase_val(); rgb_matrix_increase_val();
} }
} }
return true; return true;
case KC_AP_RGB_VAD: case KC_AP_RGB_VAD:
if (record->event.pressed) { if (record->event.pressed) {
if (get_mods() & MOD_MASK_SHIFT) { if (get_mods() & MOD_MASK_SHIFT) {
rgb_matrix_increase_sat(); rgb_matrix_increase_sat();
return false; return false;
} else if (get_mods() & MOD_MASK_CTRL) { } else if (get_mods() & MOD_MASK_CTRL) {
rgb_matrix_decrease_sat(); rgb_matrix_decrease_sat();
return false; return false;
} else { } else {
rgb_matrix_decrease_val(); rgb_matrix_decrease_val();
} }
} }
return true; return true;
case KC_AP_RGB_TOG: case KC_AP_RGB_TOG:
if (record->event.pressed) { if (record->event.pressed) {
if (get_mods() & MOD_MASK_SHIFT) { if (get_mods() & MOD_MASK_SHIFT) {
rgb_matrix_increase_speed(); rgb_matrix_increase_speed();
return false; return false;
} else if (get_mods() & MOD_MASK_CTRL) { } else if (get_mods() & MOD_MASK_CTRL) {
rgb_matrix_decrease_speed(); rgb_matrix_decrease_speed();
return false; return false;
} else { } else {
if (led_enabled) { if (led_enabled) {
ap2_led_disable(); ap2_led_disable();
rgb_matrix_disable(); rgb_matrix_disable();
led_enabled = 0; led_enabled = 0;
} else { } else {
ap2_led_enable(); ap2_led_enable();
rgb_matrix_enable(); rgb_matrix_enable();
led_enabled = 1; led_enabled = 1;
} }
return true; return true;
} }
} }
return true; return true;
case KC_AP_RGB_MOD: case KC_AP_RGB_MOD:
if (record->event.pressed) { if (record->event.pressed) {
if (get_mods() & MOD_MASK_CTRL) { if (get_mods() & MOD_MASK_CTRL) {
rgb_matrix_step_reverse(); rgb_matrix_step_reverse();
return false; return false;
} else { } else {
rgb_matrix_step(); rgb_matrix_step();
} }
} }
return true; return true;
#endif
default: default:
break; break;

View File

@ -46,3 +46,6 @@
#define MATRIX_COL_PINS \ #define MATRIX_COL_PINS \
{ C4, C5, B10, B11, C0, A15, A8, A10, A11, A12, A13, A14, B2, B3 } { C4, C5, B10, B11, C0, A15, A8, A10, A11, A12, A13, A14, B2, B3 }
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD

View File

@ -1 +0,0 @@
AnnePro2, ANSI C15 version.

View File

@ -1,12 +1,3 @@
# Anne Pro 2
SRC = \
matrix.c \
annepro2_ble.c \
ap2_led.c \
protocol.c \
rgb_driver.c \
config_led.c
# MCU # MCU
MCU = cortex-m0plus MCU = cortex-m0plus
ARMV = 6 ARMV = 6
@ -18,23 +9,44 @@ MCU_STARTUP = ht32f523xx
BOARD = ANNEPRO2_C15 BOARD = ANNEPRO2_C15
# Options # Bootloader selection
BOOTLOADER = custom
PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = no # Enable N-Key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
# Custom RGB matrix handling
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = custom
# Keys # Keys
CUSTOM_MATRIX = lite CUSTOM_MATRIX = lite
NKRO_ENABLE = no
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
KEY_LOCK_ENABLE = no KEY_LOCK_ENABLE = no
LAYOUTS = 60_ansi
# Other featues # Other features
BOOTMAGIC_ENABLE = no
CONSOLE_ENABLE = no
COMMAND_ENABLE = no
RAW_ENABLE = no RAW_ENABLE = no
MIDI_ENABLE = no MIDI_ENABLE = no
VIRTSER_ENABLE = no VIRTSER_ENABLE = no
COMBO_ENABLE = no COMBO_ENABLE = no
BOOTLOADER = custom
PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin LAYOUTS = 60_ansi
# Anne Pro 2
SRC = \
matrix.c \
annepro2_ble.c \
ap2_led.c \
protocol.c \
rgb_driver.c \
config_led.c

View File

@ -44,3 +44,6 @@
// inputs (columns are sampled) // inputs (columns are sampled)
#define MATRIX_COL_PINS \ #define MATRIX_COL_PINS \
{ C4, C5, D0, B15, C11, A15, C12, C13, A8, A10, A11, A14, D2, D3 } { C4, C5, D0, B15, C11, A15, C12, C13, A8, A10, A11, A14, D2, D3 }
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD

View File

@ -1 +0,0 @@
AnnePro2, ANSI C18 version.

View File

@ -1,12 +1,3 @@
# Anne Pro 2
SRC = \
matrix.c \
annepro2_ble.c \
ap2_led.c \
protocol.c \
rgb_driver.c \
config_led.c
# MCU # MCU
MCU = cortex-m0plus MCU = cortex-m0plus
ARMV = 6 ARMV = 6
@ -18,23 +9,44 @@ MCU_STARTUP = ht32f523xx
BOARD = ANNEPRO2_C18 BOARD = ANNEPRO2_C18
# Options # Bootloader selection
BOOTLOADER = custom
PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = no # Enable N-Key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
# Custom RGB matrix handling
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = custom
# Keys # Keys
CUSTOM_MATRIX = lite CUSTOM_MATRIX = lite
NKRO_ENABLE = no
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
KEY_LOCK_ENABLE = no KEY_LOCK_ENABLE = no
LAYOUTS = 60_ansi
# Other featues # Other features
BOOTMAGIC_ENABLE = yes
CONSOLE_ENABLE = no
COMMAND_ENABLE = no
RAW_ENABLE = no RAW_ENABLE = no
MIDI_ENABLE = no MIDI_ENABLE = no
VIRTSER_ENABLE = no VIRTSER_ENABLE = no
COMBO_ENABLE = no COMBO_ENABLE = no
BOOTLOADER = custom
PROGRAM_CMD = annepro2_tools --boot $(BUILD_DIR)/$(TARGET).bin LAYOUTS = 60_ansi
# Anne Pro 2
SRC = \
matrix.c \
annepro2_ble.c \
ap2_led.c \
protocol.c \
rgb_driver.c \
config_led.c

View File

@ -1,329 +1,75 @@
{ {
"keyboard_name": "Anne Pro 2", "keyboard_name": "Anne Pro 2",
"url": "https://openannepro.github.io/", "url": "https://openannepro.github.io/",
"maintainer": "community", "maintainer": "bwisn",
"layouts": { "layouts": {
"LAYOUT_60_ansi": { "LAYOUT_60_ansi": {
"layout": [ "layout": [
{ {"label":"~", "x":0, "y":0},
"label": "~", {"label":"!", "x":1, "y":0},
"x": 0, {"label":"@", "x":2, "y":0},
"y": 0 {"label":"#", "x":3, "y":0},
}, {"label":"$", "x":4, "y":0},
{ {"label":"%", "x":5, "y":0},
"label": "!", {"label":"^", "x":6, "y":0},
"x": 1, {"label":"&", "x":7, "y":0},
"y": 0 {"label":"*", "x":8, "y":0},
}, {"label":"(", "x":9, "y":0},
{ {"label":")", "x":10, "y":0},
"label": "@", {"label":"_", "x":11, "y":0},
"x": 2, {"label":"+", "x":12, "y":0},
"y": 0 {"label":"Backspace", "x":13, "y":0, "w":2},
},
{ {"label":"Tab", "x":0, "y":1, "w":1.5},
"label": "#", {"label":"Q", "x":1.5, "y":1},
"x": 3, {"label":"W", "x":2.5, "y":1},
"y": 0 {"label":"E", "x":3.5, "y":1},
}, {"label":"R", "x":4.5, "y":1},
{ {"label":"T", "x":5.5, "y":1},
"label": "$", {"label":"Y", "x":6.5, "y":1},
"x": 4, {"label":"U", "x":7.5, "y":1},
"y": 0 {"label":"I", "x":8.5, "y":1},
}, {"label":"O", "x":9.5, "y":1},
{ {"label":"P", "x":10.5, "y":1},
"label": "%", {"label":"{", "x":11.5, "y":1},
"x": 5, {"label":"}", "x":12.5, "y":1},
"y": 0 {"label":"|", "x":13.5, "y":1, "w":1.5},
},
{ {"label":"Caps Lock", "x":0, "y":2, "w":1.75},
"label": "^", {"label":"A", "x":1.75, "y":2},
"x": 6, {"label":"S", "x":2.75, "y":2},
"y": 0 {"label":"D", "x":3.75, "y":2},
}, {"label":"F", "x":4.75, "y":2},
{ {"label":"G", "x":5.75, "y":2},
"label": "&", {"label":"H", "x":6.75, "y":2},
"x": 7, {"label":"J", "x":7.75, "y":2},
"y": 0 {"label":"K", "x":8.75, "y":2},
}, {"label":"L", "x":9.75, "y":2},
{ {"label":":", "x":10.75, "y":2},
"label": "*", {"label":"\"", "x":11.75, "y":2},
"x": 8, {"label":"Enter", "x":12.75, "y":2, "w":2.25},
"y": 0
}, {"label":"Shift", "x":0, "y":3, "w":2.25},
{ {"label":"Z", "x":2.25, "y":3},
"label": "(", {"label":"X", "x":3.25, "y":3},
"x": 9, {"label":"C", "x":4.25, "y":3},
"y": 0 {"label":"V", "x":5.25, "y":3},
}, {"label":"B", "x":6.25, "y":3},
{ {"label":"N", "x":7.25, "y":3},
"label": ")", {"label":"M", "x":8.25, "y":3},
"x": 10, {"label":"<", "x":9.25, "y":3},
"y": 0 {"label":">", "x":10.25, "y":3},
}, {"label":"?", "x":11.25, "y":3},
{ {"label":"Shift", "x":12.25, "y":3, "w":2.75},
"label": "_",
"x": 11, {"label":"Ctrl", "x":0, "y":4, "w":1.25},
"y": 0 {"label":"Win", "x":1.25, "y":4, "w":1.25},
}, {"label":"Alt", "x":2.5, "y":4, "w":1.25},
{ {"x":3.75, "y":4, "w":6.25},
"label": "+", {"label":"Alt", "x":10, "y":4, "w":1.25},
"x": 12, {"label":"Win", "x":11.25, "y":4, "w":1.25},
"y": 0 {"label":"Menu", "x":12.5, "y":4, "w":1.25},
}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}
{
"label": "Backspace",
"x": 13,
"y": 0,
"w": 2
},
{
"label": "Tab",
"x": 0,
"y": 1,
"w": 1.5
},
{
"label": "Q",
"x": 1.5,
"y": 1
},
{
"label": "W",
"x": 2.5,
"y": 1
},
{
"label": "E",
"x": 3.5,
"y": 1
},
{
"label": "R",
"x": 4.5,
"y": 1
},
{
"label": "T",
"x": 5.5,
"y": 1
},
{
"label": "Y",
"x": 6.5,
"y": 1
},
{
"label": "U",
"x": 7.5,
"y": 1
},
{
"label": "I",
"x": 8.5,
"y": 1
},
{
"label": "O",
"x": 9.5,
"y": 1
},
{
"label": "P",
"x": 10.5,
"y": 1
},
{
"label": "{",
"x": 11.5,
"y": 1
},
{
"label": "}",
"x": 12.5,
"y": 1
},
{
"label": "|",
"x": 13.5,
"y": 1,
"w": 1.5
},
{
"label": "Caps Lock",
"x": 0,
"y": 2,
"w": 1.75
},
{
"label": "A",
"x": 1.75,
"y": 2
},
{
"label": "S",
"x": 2.75,
"y": 2
},
{
"label": "D",
"x": 3.75,
"y": 2
},
{
"label": "F",
"x": 4.75,
"y": 2
},
{
"label": "G",
"x": 5.75,
"y": 2
},
{
"label": "H",
"x": 6.75,
"y": 2
},
{
"label": "J",
"x": 7.75,
"y": 2
},
{
"label": "K",
"x": 8.75,
"y": 2
},
{
"label": "L",
"x": 9.75,
"y": 2
},
{
"label": ":",
"x": 10.75,
"y": 2
},
{
"label": "\"",
"x": 11.75,
"y": 2
},
{
"label": "Enter",
"x": 12.75,
"y": 2,
"w": 2.25
},
{
"label": "Shift",
"x": 0,
"y": 3,
"w": 2.25
},
{
"label": "Z",
"x": 2.25,
"y": 3
},
{
"label": "X",
"x": 3.25,
"y": 3
},
{
"label": "C",
"x": 4.25,
"y": 3
},
{
"label": "V",
"x": 5.25,
"y": 3
},
{
"label": "B",
"x": 6.25,
"y": 3
},
{
"label": "N",
"x": 7.25,
"y": 3
},
{
"label": "M",
"x": 8.25,
"y": 3
},
{
"label": "<",
"x": 9.25,
"y": 3
},
{
"label": ">",
"x": 10.25,
"y": 3
},
{
"label": "?",
"x": 11.25,
"y": 3
},
{
"label": "Shift",
"x": 12.25,
"y": 3,
"w": 2.75
},
{
"label": "Ctrl",
"x": 0,
"y": 4,
"w": 1.25
},
{
"label": "Win",
"x": 1.25,
"y": 4,
"w": 1.25
},
{
"label": "Alt",
"x": 2.5,
"y": 4,
"w": 1.25
},
{
"x": 3.75,
"y": 4,
"w": 6.25
},
{
"label": "Alt",
"x": 10,
"y": 4,
"w": 1.25
},
{
"label": "Win",
"x": 11.25,
"y": 4,
"w": 1.25
},
{
"label": "Menu",
"x": 12.5,
"y": 4,
"w": 1.25
},
{
"label": "Ctrl",
"x": 13.75,
"y": 4,
"w": 1.25
}
] ]
} }
} }

View File

@ -1,20 +0,0 @@
/* Copyright 2021 OpenAnnePro community
*
* 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
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD

View File

@ -1,20 +0,0 @@
/* Copyright 2021 OpenAnnePro community
*
* 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
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD

View File

@ -1,20 +0,0 @@
/* Copyright 2021 OpenAnnePro community
*
* 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
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD

View File

@ -1,3 +0,0 @@
# Custom RGB matrix handling
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = custom

View File

@ -1,12 +1,10 @@
# Anne Pro 2 rev. C15 and C18 QMK firmware # Anne Pro 2 rev. C15 and C18 QMK firmware
## Introduction An ANSI-layout 60% keyboard featuring Bluetooth support and per-key RGB lighting.
This is the QMK firmware repository for the Anne Pro 2 rev. C15 and C18 keyboard. * Keyboard Maintainer: [bwisn](https://github.com/bwisn)
* Hardware Supported: Anne Pro 2, [C15](c15/) and [C18](c18/) versions
## Layouts * Hardware Availability: [annepro.net](https://www.annepro.net/), [Hexcore](https://www.hexcore.xyz/annepro2)
Keyboard has 60% ANSI standard layout.
## How to compile ## How to compile
@ -25,26 +23,26 @@ If you want to compile the Anne Pro 2 C15 default keymap use:
If you want the executable instead of compiling it yourself, [download it here](https://ci.codetector.org/job/OpenAnnePro/job/AnnePro2-Tools/job/master/). If you want the executable instead of compiling it yourself, [download it here](https://ci.codetector.org/job/OpenAnnePro/job/AnnePro2-Tools/job/master/).
Windows and Linux versions are available. Otherwise, follow the steps below: Windows and Linux versions are available. Otherwise, follow the steps below:
0. Install the latest stable `rust` toolchain using [rustup](https://rustup.rs/) 1. Install the latest stable `rust` toolchain using [rustup](https://rustup.rs/)
0. Also install [Visual Studio Community edition](https://visualstudio.microsoft.com/downloads/) 1. Also install [Visual Studio Community edition](https://visualstudio.microsoft.com/downloads/)
including the C/C++ module to prevent errors while compiling including the C/C++ module to prevent errors while compiling
0. Download or Clone the [AnnePro2-Tools](https://github.com/OpenAnnePro/AnnePro2-Tools) project. 1. Download or Clone the [AnnePro2-Tools](https://github.com/OpenAnnePro/AnnePro2-Tools) project.
0. Compile the tool using 1. Compile the tool using
```bash ```bash
cargo build --release cargo build --release
``` ```
0. The compiled tool should be in `./target/release/annepro2_tools` (In later I will refer to this as `annepro2_tools`) The compiled tool should be in `./target/release/annepro2_tools` (In later I will refer to this as `annepro2_tools`)
### Flashing the firmware ### Flashing the firmware
0. Put the keyboard into DFU/IAP mode by unplugging the keyboard, then holding ESC while plugging it back in.
0. Run annepro2_tools with the firmware you just built.
**Please substitute with the correct paths and correct bin file if you chose another keymap profile** 1. Put the keyboard into DFU/IAP mode by unplugging the keyboard, then holding ESC while plugging it back in.
```bash 1. Run annepro2_tools with the firmware you just built.
annepro2_tools annepro2_c15_default.bin **Please substitute with the correct paths and correct bin file if you chose another keymap profile.**
``` ```bash
annepro2_tools annepro2_c15_default.bin
```
If the tool can't find the keyboard please double check you have the keyboard in IAP mode. If the tool can't find the keyboard please double check you have the keyboard in IAP mode.
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). 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).